summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Allbery <rra@stanford.edu>2010-02-21 17:45:55 -0800
committerRuss Allbery <rra@stanford.edu>2010-02-21 17:45:55 -0800
commit60210334fa3dbd5dd168199063c6ee850d750d0c (patch)
tree31e832ba6788076075d38e20ffd27ebf09430407
parente571a8eb96f42de5a114cf11ff1c3d63e5a8d301 (diff)
Imported Upstream version 0.10
-rw-r--r--.gitignore47
-rw-r--r--LICENSE5
-rw-r--r--Makefile.am190
-rw-r--r--Makefile.in1677
-rw-r--r--NEWS83
-rw-r--r--README102
-rw-r--r--TODO285
-rw-r--r--aclocal.m41170
-rwxr-xr-xautogen23
-rwxr-xr-xbuild-aux/compile143
-rwxr-xr-xbuild-aux/depcomp630
-rwxr-xr-xbuild-aux/install-sh520
-rwxr-xr-xbuild-aux/missing376
-rw-r--r--client/file.c29
-rw-r--r--client/internal.h37
-rw-r--r--client/keytab.c48
-rw-r--r--client/krb5.c53
-rw-r--r--client/remctl.c61
-rw-r--r--client/srvtab.c28
-rw-r--r--client/wallet.1513
-rw-r--r--client/wallet.c48
-rw-r--r--client/wallet.pod79
-rw-r--r--config.h.in192
-rw-r--r--config/wallet2
-rwxr-xr-xconfigure10743
-rw-r--r--configure.ac57
-rwxr-xr-xcontrib/convert-srvtab-db1
-rwxr-xr-xcontrib/used-principals1
-rwxr-xr-xcontrib/wallet-contacts193
-rwxr-xr-xcontrib/wallet-summary (renamed from contrib/wallet-report)23
-rw-r--r--contrib/wallet-summary.8179
-rw-r--r--docs/setup8
-rw-r--r--docs/stanford-naming38
-rw-r--r--examples/stanford.conf2
-rw-r--r--kasetkey/README15
-rw-r--r--kasetkey/kasetkey.c583
-rw-r--r--kasetkey/kasetkey.pod148
-rw-r--r--m4/gssapi.m4102
-rw-r--r--m4/kaserver.m495
-rw-r--r--m4/krb4.m4153
-rw-r--r--m4/krb5.m4165
-rw-r--r--m4/lib-depends.m45
-rw-r--r--m4/lib-pathname.m455
-rw-r--r--m4/remctl.m480
-rw-r--r--m4/snprintf.m418
-rw-r--r--m4/vamacros.m456
-rw-r--r--perl/Makefile.PL.in1
-rw-r--r--perl/Wallet/ACL.pm111
-rw-r--r--perl/Wallet/ACL/Base.pm32
-rw-r--r--perl/Wallet/ACL/Krb5.pm14
-rw-r--r--perl/Wallet/ACL/NetDB.pm27
-rw-r--r--perl/Wallet/ACL/NetDB/Root.pm47
-rw-r--r--perl/Wallet/Admin.pm107
-rw-r--r--perl/Wallet/Config.pm298
-rw-r--r--perl/Wallet/Database.pm18
-rw-r--r--perl/Wallet/Kadmin.pm239
-rw-r--r--perl/Wallet/Kadmin/Heimdal.pm286
-rw-r--r--perl/Wallet/Kadmin/MIT.pm322
-rw-r--r--perl/Wallet/Object/Base.pm238
-rw-r--r--perl/Wallet/Object/File.pm30
-rw-r--r--perl/Wallet/Object/Keytab.pm756
-rw-r--r--perl/Wallet/Report.pm425
-rw-r--r--perl/Wallet/Schema.pm140
-rw-r--r--perl/Wallet/Server.pm210
-rwxr-xr-xperl/t/acl.t1
-rwxr-xr-xperl/t/admin.t49
-rwxr-xr-xperl/t/config.t7
-rw-r--r--perl/t/data/README1
-rwxr-xr-xperl/t/data/keytab-fake1
-rw-r--r--perl/t/data/keytab.conf2
-rwxr-xr-xperl/t/data/netdb-fake1
-rw-r--r--perl/t/data/netdb.conf2
-rwxr-xr-xperl/t/file.t1
-rwxr-xr-xperl/t/init.t1
-rwxr-xr-xperl/t/kadmin.t109
-rwxr-xr-xperl/t/keytab.t532
-rw-r--r--perl/t/lib/Util.pm22
-rwxr-xr-xperl/t/object.t37
-rwxr-xr-xperl/t/pod-spelling.t75
-rwxr-xr-xperl/t/pod.t15
-rwxr-xr-xperl/t/report.t171
-rwxr-xr-xperl/t/schema.t3
-rwxr-xr-xperl/t/server.t35
-rwxr-xr-xperl/t/verifier-netdb.t1
-rwxr-xr-xperl/t/verifier.t1
-rw-r--r--portable/asprintf.c6
-rw-r--r--portable/dummy.c3
-rw-r--r--portable/krb5-extra.c125
-rw-r--r--portable/krb5.h83
-rw-r--r--portable/macros.h3
-rw-r--r--portable/mkstemp.c87
-rw-r--r--portable/setenv.c61
-rw-r--r--portable/snprintf.c10
-rw-r--r--portable/stdbool.h7
-rw-r--r--portable/strlcat.c3
-rw-r--r--portable/strlcpy.c3
-rw-r--r--portable/system.h39
-rw-r--r--portable/uio.h27
-rwxr-xr-xserver/keytab-backend65
-rw-r--r--server/keytab-backend.8185
-rwxr-xr-xserver/wallet-admin108
-rw-r--r--server/wallet-admin.8269
-rwxr-xr-xserver/wallet-backend126
-rw-r--r--server/wallet-backend.8357
-rwxr-xr-xserver/wallet-report203
-rw-r--r--server/wallet-report.8253
-rw-r--r--tests/TESTS8
-rw-r--r--tests/client/basic-t.in268
-rw-r--r--tests/client/full-t.in46
-rw-r--r--tests/client/pod-t.in23
-rw-r--r--tests/client/prompt-t.in29
-rw-r--r--tests/data/basic.conf2
-rwxr-xr-xtests/data/cmd-fake61
-rwxr-xr-x[-rw-r--r--]tests/data/cmd-wrapper (renamed from tests/data/cmd-wrapper.in)6
-rwxr-xr-xtests/data/fake-kadmin1
-rw-r--r--tests/data/fake-srvtabbin47 -> 50 bytes
-rw-r--r--tests/data/full.conf4
-rw-r--r--tests/data/full.conf.in4
-rw-r--r--tests/data/wallet.conf1
-rwxr-xr-xtests/docs/pod-spelling-t80
-rwxr-xr-xtests/docs/pod-t21
-rw-r--r--tests/kasetkey/basic-t.in128
-rw-r--r--tests/libtest.c204
-rw-r--r--tests/libtest.h70
-rw-r--r--tests/libtest.sh82
-rw-r--r--tests/portable/asprintf-t.c37
-rw-r--r--tests/portable/mkstemp-t.c73
-rw-r--r--tests/portable/mkstemp.c2
-rw-r--r--tests/portable/setenv-t.c46
-rw-r--r--tests/portable/setenv.c2
-rw-r--r--tests/portable/snprintf-t.c126
-rw-r--r--tests/portable/strlcat-t.c87
-rw-r--r--tests/portable/strlcpy-t.c76
-rw-r--r--tests/runtests.c330
-rwxr-xr-x[-rw-r--r--]tests/server/admin-t (renamed from tests/server/admin-t.in)72
-rwxr-xr-x[-rw-r--r--]tests/server/backend-t (renamed from tests/server/backend-t.in)38
-rwxr-xr-x[-rw-r--r--]tests/server/keytab-t (renamed from tests/server/keytab-t.in)9
-rw-r--r--tests/server/pod-t.in23
-rwxr-xr-xtests/server/report-t151
-rw-r--r--tests/tap/basic.c356
-rw-r--r--tests/tap/basic.h98
-rw-r--r--tests/tap/kerberos.c164
-rw-r--r--tests/tap/kerberos.h32
-rw-r--r--tests/tap/kerberos.sh48
-rw-r--r--tests/tap/libtap.sh148
-rw-r--r--tests/tap/messages.c80
-rw-r--r--tests/tap/messages.h35
-rw-r--r--tests/tap/process.c100
-rw-r--r--tests/tap/process.h37
-rw-r--r--tests/tap/remctl.sh46
-rw-r--r--tests/util/concat-t.c63
-rw-r--r--tests/util/messages-krb5-t.c99
-rw-r--r--tests/util/messages-t.c204
-rwxr-xr-xtests/util/xmalloc-t127
-rw-r--r--tests/util/xmalloc-t.in127
-rw-r--r--tests/util/xmalloc.c88
-rw-r--r--util/concat.c6
-rw-r--r--util/concat.h36
-rw-r--r--util/macros.h17
-rw-r--r--util/messages-krb5.c77
-rw-r--r--util/messages-krb5.h39
-rw-r--r--util/messages.c32
-rw-r--r--util/messages.h96
-rw-r--r--util/util.h172
-rw-r--r--util/xmalloc.c27
-rw-r--r--util/xmalloc.h100
166 files changed, 24724 insertions, 5292 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..10cfbf8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,47 @@
+/Makefile.in
+/aclocal.m4
+/build-aux/
+/client/wallet
+/config.h
+/config.h.in
+/config.h.in~
+/config.log
+/config.status
+/configure
+/perl/Makefile.PL
+/perl/Makefile.old
+/perl/blib/
+/perl/pm_to_blib
+/perl/t/data/test.keytab
+/perl/t/data/test.principal
+/perl/t/data/test.realm
+/perl/t/data/test.krbtype
+/tests/client/basic-t
+/tests/client/full-t
+/tests/client/prompt-t
+/tests/data/.placeholder
+/tests/data/test.keytab
+/tests/data/test.password
+/tests/data/test.principal
+/tests/data/test.krbtype
+/tests/portable/asprintf-t
+/tests/portable/mkstemp-t
+/tests/portable/setenv-t
+/tests/portable/snprintf-t
+/tests/portable/strlcat-t
+/tests/portable/strlcpy-t
+/tests/runtests
+/tests/util/concat-t
+/tests/util/messages-krb5-t
+/tests/util/messages-t
+/tests/util/xmalloc
+/wallet-*.tar.gz
+/stamp-h1
+.deps
+.dirstamp
+.libs/
+Makefile
+*.1
+*.8
+*.a
+*.o
diff --git a/LICENSE b/LICENSE
index 8eca7ad..bd01ed1 100644
--- a/LICENSE
+++ b/LICENSE
@@ -74,8 +74,9 @@ license:
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
The files portable/asprintf.c, portable/dummy.c, portable/macros.h,
-portable/stdbool.h, portable/strlcat.c, portable/strlcpy.c, and
-util/concat.c have been placed in the public domain by their author.
+portable/stdbool.h, portable/strlcat.c, portable/strlcpy.c,
+portable/uio.h, and util/concat.c have been placed in the public domain by
+their author.
The file portable/snprintf.c is released under the following license:
diff --git a/Makefile.am b/Makefile.am
index 05f7b8c..d5dccd9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,8 +1,8 @@
-# Makefile.am -- Automake makefile for wallet.
-# $Id$
+# Automake makefile for wallet.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2006, 2007, 2008, 2010
+# Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -10,45 +10,56 @@
# and are not generated or touched by configure. They're listed here to be
# added to EXTRA_DIST and so that they can be copied over properly for
# builddir != srcdir builds.
-PERL_FILES = perl/Wallet/ACL.pm perl/Wallet/ACL/Base.pm \
- perl/Wallet/ACL/Krb5.pm perl/Wallet/ACL/NetDB.pm \
- perl/Wallet/ACL/NetDB/Root.pm perl/Wallet/Admin.pm \
- perl/Wallet/Config.pm perl/Wallet/Database.pm \
- perl/Wallet/Object/Base.pm perl/Wallet/Object/File.pm \
- perl/Wallet/Object/Keytab.pm perl/Wallet/Schema.pm \
- perl/Wallet/Server.pm perl/t/acl.t perl/t/admin.t perl/t/config.t \
- perl/t/data/README perl/t/data/keytab-fake perl/t/data/keytab.conf \
- perl/t/data/netdb.conf perl/t/data/netdb-fake perl/t/init.t \
- perl/t/keytab.t perl/t/lib/Util.pm perl/t/object.t perl/t/pod.t \
- perl/t/schema.t perl/t/server.t perl/t/verifier-netdb.t \
+PERL_FILES = perl/Wallet/ACL.pm perl/Wallet/ACL/Base.pm \
+ perl/Wallet/ACL/Krb5.pm perl/Wallet/ACL/NetDB.pm \
+ perl/Wallet/ACL/NetDB/Root.pm perl/Wallet/Admin.pm \
+ perl/Wallet/Config.pm perl/Wallet/Database.pm perl/Wallet/Kadmin.pm \
+ perl/Wallet/Kadmin/Heimdal.pm perl/Wallet/Kadmin/MIT.pm \
+ perl/Wallet/Object/Base.pm perl/Wallet/Object/File.pm \
+ perl/Wallet/Object/Keytab.pm perl/Wallet/Report.pm \
+ perl/Wallet/Schema.pm perl/Wallet/Server.pm perl/t/acl.t \
+ perl/t/admin.t perl/t/config.t perl/t/data/README \
+ perl/t/data/keytab-fake perl/t/data/keytab.conf \
+ perl/t/data/netdb.conf perl/t/data/netdb-fake perl/t/file.t \
+ perl/t/init.t perl/t/kadmin.t perl/t/keytab.t perl/t/lib/Util.pm \
+ perl/t/object.t perl/t/pod-spelling.t perl/t/pod.t perl/t/report.t \
+ perl/t/schema.t perl/t/server.t perl/t/verifier-netdb.t \
perl/t/verifier.t
-TEST_FILES = tests/TESTS tests/data/README tests/data/allow-extract \
- tests/data/basic.conf tests/data/cmd-fake tests/data/fake-data \
- tests/data/fake-kadmin tests/data/fake-keytab \
- tests/data/fake-keytab-2 tests/data/fake-keytab-merge \
- tests/data/fake-keytab-old tests/data/fake-srvtab \
- tests/data/wallet.conf tests/libtest.sh
AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I m4
-EXTRA_DIST = LICENSE autogen client/wallet.pod config/allow-extract \
- config/keytab config/keytab.acl config/wallet docs/design \
- contrib/README contrib/wallet-report contrib/wallet-report.8 \
- docs/design-acl docs/design-api docs/netdb-role-api docs/notes \
- docs/setup examples/stanford.conf kasetkey/README \
- kasetkey/kasetkey.pod $(PERL_FILES) $(TEST_FILES)
+EXTRA_DIST = .gitignore LICENSE autogen client/wallet.pod \
+ config/allow-extract config/keytab config/keytab.acl config/wallet \
+ docs/design contrib/README contrib/convert-srvtab-db \
+ contrib/used-principals contrib/wallet-contacts \
+ contrib/wallet-summary contrib/wallet-summary.8 docs/design-acl \
+ docs/design-api docs/netdb-role-api docs/notes docs/setup \
+ docs/stanford-naming examples/stanford.conf tests/TESTS \
+ tests/data/README tests/data/allow-extract tests/data/basic.conf \
+ tests/data/cmd-fake tests/data/cmd-wrapper tests/data/fake-data \
+ tests/data/fake-kadmin tests/data/fake-keytab \
+ tests/data/fake-keytab-2 tests/data/fake-keytab-merge \
+ tests/data/fake-keytab-old tests/data/fake-srvtab \
+ tests/data/full.conf tests/data/wallet.conf \
+ tests/docs/pod-spelling-t tests/docs/pod-t tests/server/admin-t \
+ tests/server/backend-t tests/server/keytab-t tests/server/report-t \
+ tests/tap/kerberos.sh tests/tap/libtap.sh tests/tap/remctl.sh \
+ tests/util/xmalloc-t $(PERL_FILES)
noinst_LIBRARIES = portable/libportable.a util/libutil.a
-portable_libportable_a_SOURCES = portable/dummy.c portable/macros.h \
- portable/stdbool.h portable/system.h
+portable_libportable_a_SOURCES = portable/dummy.c portable/krb5-extra.c \
+ portable/krb5.h portable/macros.h portable/stdbool.h \
+ portable/system.h portable/uio.h
+portable_libportable_a_CPPFLAGS = $(KRB5_CPPFLAGS)
portable_libportable_a_LIBADD = $(LIBOBJS)
-util_libutil_a_SOURCES = util/concat.c util/messages.c util/messages-krb5.c \
- util/util.h util/xmalloc.c
+util_libutil_a_SOURCES = util/concat.c util/concat.h util/macros.h \
+ util/messages-krb5.c util/messages-krb5.h util/messages.c \
+ util/messages.h util/xmalloc.c util/xmalloc.h
util_libutil_a_CPPFLAGS = $(KRB5_CPPFLAGS)
bin_PROGRAMS = client/wallet
dist_sbin_SCRIPTS = server/keytab-backend server/wallet-admin \
- server/wallet-backend
+ server/wallet-backend server/wallet-report
client_wallet_SOURCES = client/file.c client/internal.h client/keytab.c \
client/krb5.c client/remctl.c client/srvtab.c client/wallet.c
client_wallet_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS)
@@ -57,40 +68,7 @@ client_wallet_LDADD = util/libutil.a portable/libportable.a $(REMCTL_LIBS) \
$(KRB5_LIBS)
dist_man_MANS = client/wallet.1 server/keytab-backend.8 \
- server/wallet-admin.8 server/wallet-backend.8
-
-if AFS
-sbin_PROGRAMS = kasetkey/kasetkey
-kasetkey_kasetkey_CPPFLAGS = $(AFS_CPPFLAGS) $(KRB4_CPPFLAGS)
-kasetkey_kasetkey_LDFLAGS = $(AFS_LDFLAGS) $(KRB4_LDFLAGS)
-kasetkey_kasetkey_LDADD = util/libutil.a portable/libportable.a $(AFS_LIBS) \
- $(KRB4_LIBS)
-dist_man_MANS += kasetkey/kasetkey.8
-endif
-
-$(srcdir)/client/wallet.1: $(srcdir)/client/wallet.pod
- pod2man --release=$(VERSION) --center="Administrative Commands" \
- --section=1 $(srcdir)/client/wallet.pod > $@
-
-$(srcdir)/contrib/wallet-report.8: $(srcdir)/contrib/wallet-report
- pod2man --release=$(VERSION) --center="Administrative Commands" \
- --section=8 $(srcdir)/contrib/wallet-report > $@
-
-$(srcdir)/kasetkey/kasetkey.8: $(srcdir)/kasetkey/kasetkey.pod
- pod2man --release=$(VERSION) --center="Administrative Commands" \
- --section=8 $(srcdir)/kasetkey/kasetkey.pod > $@
-
-$(srcdir)/server/keytab-backend.8: $(srcdir)/server/keytab-backend
- pod2man --release=$(VERSION) --center="Administrative Commands" \
- --section=8 $(srcdir)/server/keytab-backend > $@
-
-$(srcdir)/server/wallet-admin.8: $(srcdir)/server/wallet-admin
- pod2man --release=$(VERSION) --center="Administrative Commands" \
- --section=8 $(srcdir)/server/wallet-admin > $@
-
-$(srcdir)/server/wallet-backend.8: $(srcdir)/server/wallet-backend
- pod2man --release=$(VERSION) --center="Administrative Commands" \
- --section=8 $(srcdir)/server/wallet-backend > $@
+ server/wallet-admin.8 server/wallet-backend.8 server/wallet-report.8
# A set of flags for warnings. Add -O because gcc won't find some warnings
# without optimization turned on, and add -DDEBUG=1 so we'll also compile all
@@ -100,15 +78,16 @@ WARNINGS = -g -O -DDEBUG=1 -Wall -W -Wendif-labels -Wpointer-arith \
-Wmissing-prototypes -Wnested-externs -Werror
warnings:
- $(MAKE) CFLAGS='$(WARNINGS)'
- $(MAKE) CFLAGS='$(WARNINGS)' $(check_PROGRAMS)
+ $(MAKE) V=0 CFLAGS='$(WARNINGS)'
+ $(MAKE) V=0 CFLAGS='$(WARNINGS)' $(check_PROGRAMS)
# Remove some additional files.
-DISTCLEANFILES = perl/Makefile
-MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.h.in config.h.in~ \
- configure client/wallet.1 kasetkey/kasetkey.8 \
- server/keytab-backend.8 server/wallet-backend.8 tools/compile \
- tools/depcomp tools/install-sh tools/missing
+DISTCLEANFILES = perl/Makefile tests/data/.placeholder
+MAINTAINERCLEANFILES = Makefile.in aclocal.m4 build-aux/compile \
+ build-aux/depcomp build-aux/install-sh build-aux/missing \
+ client/wallet.1 config.h.in config.h.in~ configure \
+ contrib/wallet-report.8 server/keytab-backend.8 \
+ server/wallet-admin.8 server/wallet-backend.8 server/wallet-report.8
# Take appropriate actions in the Perl directory as well. We don't want to
# always build the Perl directory in all-local, since otherwise Automake does
@@ -119,8 +98,8 @@ all-local: perl/blib/lib/Wallet/Config.pm
perl/blib/lib/Wallet/Config.pm:
set -e; if [ x"$(builddir)" != x"$(srcdir)" ] ; then \
mkdir perl/Wallet perl/Wallet/ACL perl/Wallet/ACL/NetDB \
- perl/Wallet/Object perl/t perl/t/data perl/t/lib \
- 2>/dev/null || true ; \
+ perl/Wallet/Kadmin perl/Wallet/Object perl/t perl/t/data \
+ perl/t/lib 2>/dev/null || true ; \
for f in $(PERL_FILES) ; do \
cp "$(srcdir)/$$f" "$(builddir)/$$f" ; \
done \
@@ -143,49 +122,54 @@ clean-local:
# Remove the files that we copy over if and only if builddir != srcdir.
distclean-local:
set -e; if [ x"$(builddir)" != x"$(srcdir)" ] ; then \
- rm -f $(PERL_FILES) $(TEST_FILES) ; \
+ rm -f $(PERL_FILES) ; \
fi
# The bits below are for the test suite, not for the main package.
-check_PROGRAMS = tests/runtests tests/portable/asprintf-t \
- tests/portable/snprintf-t tests/portable/strlcat-t \
- tests/portable/strlcpy-t tests/util/concat-t tests/util/messages-t \
- tests/util/xmalloc
-check_LIBRARIES = tests/libtest.a
-tests_libtest_a_SOURCES = tests/libtest.c tests/libtest.h
+check_PROGRAMS = tests/runtests tests/portable/asprintf-t \
+ tests/portable/mkstemp-t tests/portable/setenv-t \
+ tests/portable/snprintf-t tests/portable/strlcat-t \
+ tests/portable/strlcpy-t tests/util/concat-t \
+ tests/util/messages-krb5-t tests/util/messages-t tests/util/xmalloc
+tests_runtests_CPPFLAGS = -DSOURCE='"$(abs_top_srcdir)/tests"' \
+ -DBUILD='"$(abs_top_builddir)/tests"'
+check_LIBRARIES = tests/tap/libtap.a
+tests_tap_libtap_a_CPPFLAGS = -I$(abs_top_srcdir)/tests $(KRB5_CPPFLAGS)
+tests_tap_libtap_a_SOURCES = tests/tap/basic.c tests/tap/basic.h \
+ tests/tap/kerberos.c tests/tap/kerberos.h tests/tap/messages.c \
+ tests/tap/messages.h tests/tap/process.c tests/tap/process.h
# All of the test programs.
tests_portable_asprintf_t_SOURCES = tests/portable/asprintf-t.c \
- tests/portable/asprintf.c
-tests_portable_asprintf_t_LDADD = tests/libtest.a util/libutil.a \
- portable/libportable.a
+ tests/portable/asprintf.c
+tests_portable_asprintf_t_LDADD = tests/tap/libtap.a portable/libportable.a
+tests_portable_mkstemp_t_SOURCES = tests/portable/mkstemp-t.c \
+ tests/portable/mkstemp.c
+tests_portable_mkstemp_t_LDADD = tests/tap/libtap.a portable/libportable.a
+tests_portable_setenv_t_SOURCES = tests/portable/setenv-t.c \
+ tests/portable/setenv.c
+tests_portable_setenv_t_LDADD = tests/tap/libtap.a portable/libportable.a
tests_portable_snprintf_t_SOURCES = tests/portable/snprintf-t.c \
- tests/portable/snprintf.c
-tests_portable_snprintf_t_LDADD = tests/libtest.a util/libutil.a \
- portable/libportable.a
+ tests/portable/snprintf.c
+tests_portable_snprintf_t_LDADD = tests/tap/libtap.a portable/libportable.a
tests_portable_strlcat_t_SOURCES = tests/portable/strlcat-t.c \
- tests/portable/strlcat.c
-tests_portable_strlcat_t_LDADD = tests/libtest.a util/libutil.a \
- portable/libportable.a
+ tests/portable/strlcat.c
+tests_portable_strlcat_t_LDADD = tests/tap/libtap.a portable/libportable.a
tests_portable_strlcpy_t_SOURCES = tests/portable/strlcpy-t.c \
- tests/portable/strlcpy.c
-tests_portable_strlcpy_t_LDADD = tests/libtest.a util/libutil.a \
+ tests/portable/strlcpy.c
+tests_portable_strlcpy_t_LDADD = tests/tap/libtap.a portable/libportable.a
+tests_util_concat_t_LDADD = tests/tap/libtap.a util/libutil.a \
portable/libportable.a
-tests_util_concat_t_LDADD = tests/libtest.a util/libutil.a \
- portable/libportable.a
-tests_util_messages_t_LDADD = tests/libtest.a util/libutil.a \
+tests_util_messages_krb5_t_CPPFLAGS = $(KRB5_CPPFLAGS)
+tests_util_messages_krb5_t_LDFLAGS = $(KRB5_LDFLAGS)
+tests_util_messages_krb5_t_LDADD = tests/tap/libtap.a util/libutil.a \
+ portable/libportable.a $(KRB5_LIBS)
+tests_util_messages_t_LDADD = tests/tap/libtap.a util/libutil.a \
portable/libportable.a
tests_util_xmalloc_LDADD = util/libutil.a portable/libportable.a
check-local: $(check_PROGRAMS)
- set -e; if [ x"$(builddir)" != x"$(srcdir)" ] ; then \
- mkdir tests/data/acls 2>/dev/null || true ; \
- for f in $(TEST_FILES) ; do \
- cp "$(srcdir)/$$f" "$(builddir)/$$f" ; \
- done \
- fi
- cd tests && ./runtests TESTS
- @echo ''
+ cd tests && ./runtests $(abs_top_srcdir)/tests/TESTS
@echo ''
cd perl && $(MAKE) test
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..c08f7fa
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,1677 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Automake makefile for wallet.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2006, 2007, 2008, 2010
+# Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+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 = :
+bin_PROGRAMS = client/wallet$(EXEEXT)
+check_PROGRAMS = tests/runtests$(EXEEXT) \
+ tests/portable/asprintf-t$(EXEEXT) \
+ tests/portable/mkstemp-t$(EXEEXT) \
+ tests/portable/setenv-t$(EXEEXT) \
+ tests/portable/snprintf-t$(EXEEXT) \
+ tests/portable/strlcat-t$(EXEEXT) \
+ tests/portable/strlcpy-t$(EXEEXT) tests/util/concat-t$(EXEEXT) \
+ tests/util/messages-krb5-t$(EXEEXT) \
+ tests/util/messages-t$(EXEEXT) tests/util/xmalloc$(EXEEXT)
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \
+ $(dist_sbin_SCRIPTS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(top_srcdir)/configure $(top_srcdir)/perl/Makefile.PL.in \
+ $(top_srcdir)/tests/client/basic-t.in \
+ $(top_srcdir)/tests/client/full-t.in \
+ $(top_srcdir)/tests/client/prompt-t.in NEWS TODO \
+ build-aux/compile build-aux/depcomp build-aux/install-sh \
+ build-aux/missing portable/asprintf.c portable/mkstemp.c \
+ portable/setenv.c portable/snprintf.c portable/strlcat.c \
+ portable/strlcpy.c
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gssapi.m4 \
+ $(top_srcdir)/m4/krb5.m4 $(top_srcdir)/m4/lib-depends.m4 \
+ $(top_srcdir)/m4/lib-pathname.m4 $(top_srcdir)/m4/remctl.m4 \
+ $(top_srcdir)/m4/snprintf.m4 $(top_srcdir)/m4/vamacros.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = perl/Makefile.PL tests/client/basic-t \
+ tests/client/full-t tests/client/prompt-t
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_$(V))
+am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY))
+am__v_AR_0 = @echo " AR " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+portable_libportable_a_AR = $(AR) $(ARFLAGS)
+LIBOBJDIR = portable/
+portable_libportable_a_DEPENDENCIES = $(LIBOBJS)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_portable_libportable_a_OBJECTS = \
+ portable/portable_libportable_a-dummy.$(OBJEXT) \
+ portable/portable_libportable_a-krb5-extra.$(OBJEXT)
+portable_libportable_a_OBJECTS = $(am_portable_libportable_a_OBJECTS)
+tests_tap_libtap_a_AR = $(AR) $(ARFLAGS)
+tests_tap_libtap_a_LIBADD =
+am_tests_tap_libtap_a_OBJECTS = \
+ tests/tap/tests_tap_libtap_a-basic.$(OBJEXT) \
+ tests/tap/tests_tap_libtap_a-kerberos.$(OBJEXT) \
+ tests/tap/tests_tap_libtap_a-messages.$(OBJEXT) \
+ tests/tap/tests_tap_libtap_a-process.$(OBJEXT)
+tests_tap_libtap_a_OBJECTS = $(am_tests_tap_libtap_a_OBJECTS)
+util_libutil_a_AR = $(AR) $(ARFLAGS)
+util_libutil_a_LIBADD =
+am_util_libutil_a_OBJECTS = util/util_libutil_a-concat.$(OBJEXT) \
+ util/util_libutil_a-messages-krb5.$(OBJEXT) \
+ util/util_libutil_a-messages.$(OBJEXT) \
+ util/util_libutil_a-xmalloc.$(OBJEXT)
+util_libutil_a_OBJECTS = $(am_util_libutil_a_OBJECTS)
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \
+ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_client_wallet_OBJECTS = client/client_wallet-file.$(OBJEXT) \
+ client/client_wallet-keytab.$(OBJEXT) \
+ client/client_wallet-krb5.$(OBJEXT) \
+ client/client_wallet-remctl.$(OBJEXT) \
+ client/client_wallet-srvtab.$(OBJEXT) \
+ client/client_wallet-wallet.$(OBJEXT)
+client_wallet_OBJECTS = $(am_client_wallet_OBJECTS)
+am__DEPENDENCIES_1 =
+client_wallet_DEPENDENCIES = util/libutil.a portable/libportable.a \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+client_wallet_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(client_wallet_LDFLAGS) $(LDFLAGS) -o $@
+am_tests_portable_asprintf_t_OBJECTS = \
+ tests/portable/asprintf-t.$(OBJEXT) \
+ tests/portable/asprintf.$(OBJEXT)
+tests_portable_asprintf_t_OBJECTS = \
+ $(am_tests_portable_asprintf_t_OBJECTS)
+tests_portable_asprintf_t_DEPENDENCIES = tests/tap/libtap.a \
+ portable/libportable.a
+am_tests_portable_mkstemp_t_OBJECTS = \
+ tests/portable/mkstemp-t.$(OBJEXT) \
+ tests/portable/mkstemp.$(OBJEXT)
+tests_portable_mkstemp_t_OBJECTS = \
+ $(am_tests_portable_mkstemp_t_OBJECTS)
+tests_portable_mkstemp_t_DEPENDENCIES = tests/tap/libtap.a \
+ portable/libportable.a
+am_tests_portable_setenv_t_OBJECTS = \
+ tests/portable/setenv-t.$(OBJEXT) \
+ tests/portable/setenv.$(OBJEXT)
+tests_portable_setenv_t_OBJECTS = \
+ $(am_tests_portable_setenv_t_OBJECTS)
+tests_portable_setenv_t_DEPENDENCIES = tests/tap/libtap.a \
+ portable/libportable.a
+am_tests_portable_snprintf_t_OBJECTS = \
+ tests/portable/snprintf-t.$(OBJEXT) \
+ tests/portable/snprintf.$(OBJEXT)
+tests_portable_snprintf_t_OBJECTS = \
+ $(am_tests_portable_snprintf_t_OBJECTS)
+tests_portable_snprintf_t_DEPENDENCIES = tests/tap/libtap.a \
+ portable/libportable.a
+am_tests_portable_strlcat_t_OBJECTS = \
+ tests/portable/strlcat-t.$(OBJEXT) \
+ tests/portable/strlcat.$(OBJEXT)
+tests_portable_strlcat_t_OBJECTS = \
+ $(am_tests_portable_strlcat_t_OBJECTS)
+tests_portable_strlcat_t_DEPENDENCIES = tests/tap/libtap.a \
+ portable/libportable.a
+am_tests_portable_strlcpy_t_OBJECTS = \
+ tests/portable/strlcpy-t.$(OBJEXT) \
+ tests/portable/strlcpy.$(OBJEXT)
+tests_portable_strlcpy_t_OBJECTS = \
+ $(am_tests_portable_strlcpy_t_OBJECTS)
+tests_portable_strlcpy_t_DEPENDENCIES = tests/tap/libtap.a \
+ portable/libportable.a
+tests_runtests_SOURCES = tests/runtests.c
+tests_runtests_OBJECTS = tests/tests_runtests-runtests.$(OBJEXT)
+tests_runtests_LDADD = $(LDADD)
+tests_util_concat_t_SOURCES = tests/util/concat-t.c
+tests_util_concat_t_OBJECTS = tests/util/concat-t.$(OBJEXT)
+tests_util_concat_t_DEPENDENCIES = tests/tap/libtap.a util/libutil.a \
+ portable/libportable.a
+tests_util_messages_krb5_t_SOURCES = tests/util/messages-krb5-t.c
+tests_util_messages_krb5_t_OBJECTS = tests/util/tests_util_messages_krb5_t-messages-krb5-t.$(OBJEXT)
+tests_util_messages_krb5_t_DEPENDENCIES = tests/tap/libtap.a \
+ util/libutil.a portable/libportable.a $(am__DEPENDENCIES_1)
+tests_util_messages_krb5_t_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(tests_util_messages_krb5_t_LDFLAGS) $(LDFLAGS) -o $@
+tests_util_messages_t_SOURCES = tests/util/messages-t.c
+tests_util_messages_t_OBJECTS = tests/util/messages-t.$(OBJEXT)
+tests_util_messages_t_DEPENDENCIES = tests/tap/libtap.a util/libutil.a \
+ portable/libportable.a
+tests_util_xmalloc_SOURCES = tests/util/xmalloc.c
+tests_util_xmalloc_OBJECTS = tests/util/xmalloc.$(OBJEXT)
+tests_util_xmalloc_DEPENDENCIES = util/libutil.a \
+ portable/libportable.a
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+SCRIPTS = $(dist_sbin_SCRIPTS)
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(portable_libportable_a_SOURCES) \
+ $(tests_tap_libtap_a_SOURCES) $(util_libutil_a_SOURCES) \
+ $(client_wallet_SOURCES) $(tests_portable_asprintf_t_SOURCES) \
+ $(tests_portable_mkstemp_t_SOURCES) \
+ $(tests_portable_setenv_t_SOURCES) \
+ $(tests_portable_snprintf_t_SOURCES) \
+ $(tests_portable_strlcat_t_SOURCES) \
+ $(tests_portable_strlcpy_t_SOURCES) tests/runtests.c \
+ tests/util/concat-t.c tests/util/messages-krb5-t.c \
+ tests/util/messages-t.c tests/util/xmalloc.c
+DIST_SOURCES = $(portable_libportable_a_SOURCES) \
+ $(tests_tap_libtap_a_SOURCES) $(util_libutil_a_SOURCES) \
+ $(client_wallet_SOURCES) $(tests_portable_asprintf_t_SOURCES) \
+ $(tests_portable_mkstemp_t_SOURCES) \
+ $(tests_portable_setenv_t_SOURCES) \
+ $(tests_portable_snprintf_t_SOURCES) \
+ $(tests_portable_strlcat_t_SOURCES) \
+ $(tests_portable_strlcpy_t_SOURCES) tests/runtests.c \
+ tests/util/concat-t.c tests/util/messages-krb5-t.c \
+ tests/util/messages-t.c tests/util/xmalloc.c
+man1dir = $(mandir)/man1
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d "$(distdir)" \
+ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr "$(distdir)"; }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GREP = @GREP@
+GSSAPI_CPPFLAGS = @GSSAPI_CPPFLAGS@
+GSSAPI_LDFLAGS = @GSSAPI_LDFLAGS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KRB5_CONFIG = @KRB5_CONFIG@
+KRB5_CPPFLAGS = @KRB5_CPPFLAGS@
+KRB5_LDFLAGS = @KRB5_LDFLAGS@
+KRB5_LIBS = @KRB5_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+REMCTLD = @REMCTLD@
+REMCTL_CPPFLAGS = @REMCTL_CPPFLAGS@
+REMCTL_LDFLAGS = @REMCTL_LDFLAGS@
+REMCTL_LIBS = @REMCTL_LIBS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# These two lists of files are needed for Perl builds and for the test suite
+# and are not generated or touched by configure. They're listed here to be
+# added to EXTRA_DIST and so that they can be copied over properly for
+# builddir != srcdir builds.
+PERL_FILES = perl/Wallet/ACL.pm perl/Wallet/ACL/Base.pm \
+ perl/Wallet/ACL/Krb5.pm perl/Wallet/ACL/NetDB.pm \
+ perl/Wallet/ACL/NetDB/Root.pm perl/Wallet/Admin.pm \
+ perl/Wallet/Config.pm perl/Wallet/Database.pm perl/Wallet/Kadmin.pm \
+ perl/Wallet/Kadmin/Heimdal.pm perl/Wallet/Kadmin/MIT.pm \
+ perl/Wallet/Object/Base.pm perl/Wallet/Object/File.pm \
+ perl/Wallet/Object/Keytab.pm perl/Wallet/Report.pm \
+ perl/Wallet/Schema.pm perl/Wallet/Server.pm perl/t/acl.t \
+ perl/t/admin.t perl/t/config.t perl/t/data/README \
+ perl/t/data/keytab-fake perl/t/data/keytab.conf \
+ perl/t/data/netdb.conf perl/t/data/netdb-fake perl/t/file.t \
+ perl/t/init.t perl/t/kadmin.t perl/t/keytab.t perl/t/lib/Util.pm \
+ perl/t/object.t perl/t/pod-spelling.t perl/t/pod.t perl/t/report.t \
+ perl/t/schema.t perl/t/server.t perl/t/verifier-netdb.t \
+ perl/t/verifier.t
+
+AUTOMAKE_OPTIONS = foreign subdir-objects
+ACLOCAL_AMFLAGS = -I m4
+EXTRA_DIST = .gitignore LICENSE autogen client/wallet.pod \
+ config/allow-extract config/keytab config/keytab.acl config/wallet \
+ docs/design contrib/README contrib/convert-srvtab-db \
+ contrib/used-principals contrib/wallet-contacts \
+ contrib/wallet-summary contrib/wallet-summary.8 docs/design-acl \
+ docs/design-api docs/netdb-role-api docs/notes docs/setup \
+ docs/stanford-naming examples/stanford.conf tests/TESTS \
+ tests/data/README tests/data/allow-extract tests/data/basic.conf \
+ tests/data/cmd-fake tests/data/cmd-wrapper tests/data/fake-data \
+ tests/data/fake-kadmin tests/data/fake-keytab \
+ tests/data/fake-keytab-2 tests/data/fake-keytab-merge \
+ tests/data/fake-keytab-old tests/data/fake-srvtab \
+ tests/data/full.conf tests/data/wallet.conf \
+ tests/docs/pod-spelling-t tests/docs/pod-t tests/server/admin-t \
+ tests/server/backend-t tests/server/keytab-t tests/server/report-t \
+ tests/tap/kerberos.sh tests/tap/libtap.sh tests/tap/remctl.sh \
+ tests/util/xmalloc-t $(PERL_FILES)
+
+noinst_LIBRARIES = portable/libportable.a util/libutil.a
+portable_libportable_a_SOURCES = portable/dummy.c portable/krb5-extra.c \
+ portable/krb5.h portable/macros.h portable/stdbool.h \
+ portable/system.h portable/uio.h
+
+portable_libportable_a_CPPFLAGS = $(KRB5_CPPFLAGS)
+portable_libportable_a_LIBADD = $(LIBOBJS)
+util_libutil_a_SOURCES = util/concat.c util/concat.h util/macros.h \
+ util/messages-krb5.c util/messages-krb5.h util/messages.c \
+ util/messages.h util/xmalloc.c util/xmalloc.h
+
+util_libutil_a_CPPFLAGS = $(KRB5_CPPFLAGS)
+dist_sbin_SCRIPTS = server/keytab-backend server/wallet-admin \
+ server/wallet-backend server/wallet-report
+
+client_wallet_SOURCES = client/file.c client/internal.h client/keytab.c \
+ client/krb5.c client/remctl.c client/srvtab.c client/wallet.c
+
+client_wallet_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS)
+client_wallet_LDFLAGS = $(REMCTL_LDFLAGS) $(KRB5_LDFLAGS)
+client_wallet_LDADD = util/libutil.a portable/libportable.a $(REMCTL_LIBS) \
+ $(KRB5_LIBS)
+
+dist_man_MANS = client/wallet.1 server/keytab-backend.8 \
+ server/wallet-admin.8 server/wallet-backend.8 server/wallet-report.8
+
+
+# A set of flags for warnings. Add -O because gcc won't find some warnings
+# without optimization turned on, and add -DDEBUG=1 so we'll also compile all
+# debugging code and test it.
+WARNINGS = -g -O -DDEBUG=1 -Wall -W -Wendif-labels -Wpointer-arith \
+ -Wbad-function-cast -Wwrite-strings -Wstrict-prototypes \
+ -Wmissing-prototypes -Wnested-externs -Werror
+
+
+# Remove some additional files.
+DISTCLEANFILES = perl/Makefile tests/data/.placeholder
+MAINTAINERCLEANFILES = Makefile.in aclocal.m4 build-aux/compile \
+ build-aux/depcomp build-aux/install-sh build-aux/missing \
+ client/wallet.1 config.h.in config.h.in~ configure \
+ contrib/wallet-report.8 server/keytab-backend.8 \
+ server/wallet-admin.8 server/wallet-backend.8 server/wallet-report.8
+
+tests_runtests_CPPFLAGS = -DSOURCE='"$(abs_top_srcdir)/tests"' \
+ -DBUILD='"$(abs_top_builddir)/tests"'
+
+check_LIBRARIES = tests/tap/libtap.a
+tests_tap_libtap_a_CPPFLAGS = -I$(abs_top_srcdir)/tests $(KRB5_CPPFLAGS)
+tests_tap_libtap_a_SOURCES = tests/tap/basic.c tests/tap/basic.h \
+ tests/tap/kerberos.c tests/tap/kerberos.h tests/tap/messages.c \
+ tests/tap/messages.h tests/tap/process.c tests/tap/process.h
+
+
+# All of the test programs.
+tests_portable_asprintf_t_SOURCES = tests/portable/asprintf-t.c \
+ tests/portable/asprintf.c
+
+tests_portable_asprintf_t_LDADD = tests/tap/libtap.a portable/libportable.a
+tests_portable_mkstemp_t_SOURCES = tests/portable/mkstemp-t.c \
+ tests/portable/mkstemp.c
+
+tests_portable_mkstemp_t_LDADD = tests/tap/libtap.a portable/libportable.a
+tests_portable_setenv_t_SOURCES = tests/portable/setenv-t.c \
+ tests/portable/setenv.c
+
+tests_portable_setenv_t_LDADD = tests/tap/libtap.a portable/libportable.a
+tests_portable_snprintf_t_SOURCES = tests/portable/snprintf-t.c \
+ tests/portable/snprintf.c
+
+tests_portable_snprintf_t_LDADD = tests/tap/libtap.a portable/libportable.a
+tests_portable_strlcat_t_SOURCES = tests/portable/strlcat-t.c \
+ tests/portable/strlcat.c
+
+tests_portable_strlcat_t_LDADD = tests/tap/libtap.a portable/libportable.a
+tests_portable_strlcpy_t_SOURCES = tests/portable/strlcpy-t.c \
+ tests/portable/strlcpy.c
+
+tests_portable_strlcpy_t_LDADD = tests/tap/libtap.a portable/libportable.a
+tests_util_concat_t_LDADD = tests/tap/libtap.a util/libutil.a \
+ portable/libportable.a
+
+tests_util_messages_krb5_t_CPPFLAGS = $(KRB5_CPPFLAGS)
+tests_util_messages_krb5_t_LDFLAGS = $(KRB5_LDFLAGS)
+tests_util_messages_krb5_t_LDADD = tests/tap/libtap.a util/libutil.a \
+ portable/libportable.a $(KRB5_LIBS)
+
+tests_util_messages_t_LDADD = tests/tap/libtap.a util/libutil.a \
+ portable/libportable.a
+
+tests_util_xmalloc_LDADD = util/libutil.a portable/libportable.a
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+perl/Makefile.PL: $(top_builddir)/config.status $(top_srcdir)/perl/Makefile.PL.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+tests/client/basic-t: $(top_builddir)/config.status $(top_srcdir)/tests/client/basic-t.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+tests/client/full-t: $(top_builddir)/config.status $(top_srcdir)/tests/client/full-t.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+tests/client/prompt-t: $(top_builddir)/config.status $(top_srcdir)/tests/client/prompt-t.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+
+clean-checkLIBRARIES:
+ -test -z "$(check_LIBRARIES)" || rm -f $(check_LIBRARIES)
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+portable/$(am__dirstamp):
+ @$(MKDIR_P) portable
+ @: > portable/$(am__dirstamp)
+portable/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) portable/$(DEPDIR)
+ @: > portable/$(DEPDIR)/$(am__dirstamp)
+portable/portable_libportable_a-dummy.$(OBJEXT): \
+ portable/$(am__dirstamp) portable/$(DEPDIR)/$(am__dirstamp)
+portable/portable_libportable_a-krb5-extra.$(OBJEXT): \
+ portable/$(am__dirstamp) portable/$(DEPDIR)/$(am__dirstamp)
+portable/libportable.a: $(portable_libportable_a_OBJECTS) $(portable_libportable_a_DEPENDENCIES) portable/$(am__dirstamp)
+ $(AM_V_at)-rm -f portable/libportable.a
+ $(AM_V_AR)$(portable_libportable_a_AR) portable/libportable.a $(portable_libportable_a_OBJECTS) $(portable_libportable_a_LIBADD)
+ $(AM_V_at)$(RANLIB) portable/libportable.a
+tests/tap/$(am__dirstamp):
+ @$(MKDIR_P) tests/tap
+ @: > tests/tap/$(am__dirstamp)
+tests/tap/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) tests/tap/$(DEPDIR)
+ @: > tests/tap/$(DEPDIR)/$(am__dirstamp)
+tests/tap/tests_tap_libtap_a-basic.$(OBJEXT): \
+ tests/tap/$(am__dirstamp) tests/tap/$(DEPDIR)/$(am__dirstamp)
+tests/tap/tests_tap_libtap_a-kerberos.$(OBJEXT): \
+ tests/tap/$(am__dirstamp) tests/tap/$(DEPDIR)/$(am__dirstamp)
+tests/tap/tests_tap_libtap_a-messages.$(OBJEXT): \
+ tests/tap/$(am__dirstamp) tests/tap/$(DEPDIR)/$(am__dirstamp)
+tests/tap/tests_tap_libtap_a-process.$(OBJEXT): \
+ tests/tap/$(am__dirstamp) tests/tap/$(DEPDIR)/$(am__dirstamp)
+tests/tap/libtap.a: $(tests_tap_libtap_a_OBJECTS) $(tests_tap_libtap_a_DEPENDENCIES) tests/tap/$(am__dirstamp)
+ $(AM_V_at)-rm -f tests/tap/libtap.a
+ $(AM_V_AR)$(tests_tap_libtap_a_AR) tests/tap/libtap.a $(tests_tap_libtap_a_OBJECTS) $(tests_tap_libtap_a_LIBADD)
+ $(AM_V_at)$(RANLIB) tests/tap/libtap.a
+util/$(am__dirstamp):
+ @$(MKDIR_P) util
+ @: > util/$(am__dirstamp)
+util/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) util/$(DEPDIR)
+ @: > util/$(DEPDIR)/$(am__dirstamp)
+util/util_libutil_a-concat.$(OBJEXT): util/$(am__dirstamp) \
+ util/$(DEPDIR)/$(am__dirstamp)
+util/util_libutil_a-messages-krb5.$(OBJEXT): util/$(am__dirstamp) \
+ util/$(DEPDIR)/$(am__dirstamp)
+util/util_libutil_a-messages.$(OBJEXT): util/$(am__dirstamp) \
+ util/$(DEPDIR)/$(am__dirstamp)
+util/util_libutil_a-xmalloc.$(OBJEXT): util/$(am__dirstamp) \
+ util/$(DEPDIR)/$(am__dirstamp)
+util/libutil.a: $(util_libutil_a_OBJECTS) $(util_libutil_a_DEPENDENCIES) util/$(am__dirstamp)
+ $(AM_V_at)-rm -f util/libutil.a
+ $(AM_V_AR)$(util_libutil_a_AR) util/libutil.a $(util_libutil_a_OBJECTS) $(util_libutil_a_LIBADD)
+ $(AM_V_at)$(RANLIB) util/libutil.a
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+client/$(am__dirstamp):
+ @$(MKDIR_P) client
+ @: > client/$(am__dirstamp)
+client/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) client/$(DEPDIR)
+ @: > client/$(DEPDIR)/$(am__dirstamp)
+client/client_wallet-file.$(OBJEXT): client/$(am__dirstamp) \
+ client/$(DEPDIR)/$(am__dirstamp)
+client/client_wallet-keytab.$(OBJEXT): client/$(am__dirstamp) \
+ client/$(DEPDIR)/$(am__dirstamp)
+client/client_wallet-krb5.$(OBJEXT): client/$(am__dirstamp) \
+ client/$(DEPDIR)/$(am__dirstamp)
+client/client_wallet-remctl.$(OBJEXT): client/$(am__dirstamp) \
+ client/$(DEPDIR)/$(am__dirstamp)
+client/client_wallet-srvtab.$(OBJEXT): client/$(am__dirstamp) \
+ client/$(DEPDIR)/$(am__dirstamp)
+client/client_wallet-wallet.$(OBJEXT): client/$(am__dirstamp) \
+ client/$(DEPDIR)/$(am__dirstamp)
+client/wallet$(EXEEXT): $(client_wallet_OBJECTS) $(client_wallet_DEPENDENCIES) client/$(am__dirstamp)
+ @rm -f client/wallet$(EXEEXT)
+ $(AM_V_CCLD)$(client_wallet_LINK) $(client_wallet_OBJECTS) $(client_wallet_LDADD) $(LIBS)
+tests/portable/$(am__dirstamp):
+ @$(MKDIR_P) tests/portable
+ @: > tests/portable/$(am__dirstamp)
+tests/portable/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) tests/portable/$(DEPDIR)
+ @: > tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/asprintf-t.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/asprintf.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/asprintf-t$(EXEEXT): $(tests_portable_asprintf_t_OBJECTS) $(tests_portable_asprintf_t_DEPENDENCIES) tests/portable/$(am__dirstamp)
+ @rm -f tests/portable/asprintf-t$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_portable_asprintf_t_OBJECTS) $(tests_portable_asprintf_t_LDADD) $(LIBS)
+tests/portable/mkstemp-t.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/mkstemp.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/mkstemp-t$(EXEEXT): $(tests_portable_mkstemp_t_OBJECTS) $(tests_portable_mkstemp_t_DEPENDENCIES) tests/portable/$(am__dirstamp)
+ @rm -f tests/portable/mkstemp-t$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_portable_mkstemp_t_OBJECTS) $(tests_portable_mkstemp_t_LDADD) $(LIBS)
+tests/portable/setenv-t.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/setenv.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/setenv-t$(EXEEXT): $(tests_portable_setenv_t_OBJECTS) $(tests_portable_setenv_t_DEPENDENCIES) tests/portable/$(am__dirstamp)
+ @rm -f tests/portable/setenv-t$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_portable_setenv_t_OBJECTS) $(tests_portable_setenv_t_LDADD) $(LIBS)
+tests/portable/snprintf-t.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/snprintf.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/snprintf-t$(EXEEXT): $(tests_portable_snprintf_t_OBJECTS) $(tests_portable_snprintf_t_DEPENDENCIES) tests/portable/$(am__dirstamp)
+ @rm -f tests/portable/snprintf-t$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_portable_snprintf_t_OBJECTS) $(tests_portable_snprintf_t_LDADD) $(LIBS)
+tests/portable/strlcat-t.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/strlcat.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/strlcat-t$(EXEEXT): $(tests_portable_strlcat_t_OBJECTS) $(tests_portable_strlcat_t_DEPENDENCIES) tests/portable/$(am__dirstamp)
+ @rm -f tests/portable/strlcat-t$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_portable_strlcat_t_OBJECTS) $(tests_portable_strlcat_t_LDADD) $(LIBS)
+tests/portable/strlcpy-t.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/strlcpy.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/strlcpy-t$(EXEEXT): $(tests_portable_strlcpy_t_OBJECTS) $(tests_portable_strlcpy_t_DEPENDENCIES) tests/portable/$(am__dirstamp)
+ @rm -f tests/portable/strlcpy-t$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_portable_strlcpy_t_OBJECTS) $(tests_portable_strlcpy_t_LDADD) $(LIBS)
+tests/$(am__dirstamp):
+ @$(MKDIR_P) tests
+ @: > tests/$(am__dirstamp)
+tests/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) tests/$(DEPDIR)
+ @: > tests/$(DEPDIR)/$(am__dirstamp)
+tests/tests_runtests-runtests.$(OBJEXT): tests/$(am__dirstamp) \
+ tests/$(DEPDIR)/$(am__dirstamp)
+tests/runtests$(EXEEXT): $(tests_runtests_OBJECTS) $(tests_runtests_DEPENDENCIES) tests/$(am__dirstamp)
+ @rm -f tests/runtests$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_runtests_OBJECTS) $(tests_runtests_LDADD) $(LIBS)
+tests/util/$(am__dirstamp):
+ @$(MKDIR_P) tests/util
+ @: > tests/util/$(am__dirstamp)
+tests/util/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) tests/util/$(DEPDIR)
+ @: > tests/util/$(DEPDIR)/$(am__dirstamp)
+tests/util/concat-t.$(OBJEXT): tests/util/$(am__dirstamp) \
+ tests/util/$(DEPDIR)/$(am__dirstamp)
+tests/util/concat-t$(EXEEXT): $(tests_util_concat_t_OBJECTS) $(tests_util_concat_t_DEPENDENCIES) tests/util/$(am__dirstamp)
+ @rm -f tests/util/concat-t$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_util_concat_t_OBJECTS) $(tests_util_concat_t_LDADD) $(LIBS)
+tests/util/tests_util_messages_krb5_t-messages-krb5-t.$(OBJEXT): \
+ tests/util/$(am__dirstamp) \
+ tests/util/$(DEPDIR)/$(am__dirstamp)
+tests/util/messages-krb5-t$(EXEEXT): $(tests_util_messages_krb5_t_OBJECTS) $(tests_util_messages_krb5_t_DEPENDENCIES) tests/util/$(am__dirstamp)
+ @rm -f tests/util/messages-krb5-t$(EXEEXT)
+ $(AM_V_CCLD)$(tests_util_messages_krb5_t_LINK) $(tests_util_messages_krb5_t_OBJECTS) $(tests_util_messages_krb5_t_LDADD) $(LIBS)
+tests/util/messages-t.$(OBJEXT): tests/util/$(am__dirstamp) \
+ tests/util/$(DEPDIR)/$(am__dirstamp)
+tests/util/messages-t$(EXEEXT): $(tests_util_messages_t_OBJECTS) $(tests_util_messages_t_DEPENDENCIES) tests/util/$(am__dirstamp)
+ @rm -f tests/util/messages-t$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_util_messages_t_OBJECTS) $(tests_util_messages_t_LDADD) $(LIBS)
+tests/util/xmalloc.$(OBJEXT): tests/util/$(am__dirstamp) \
+ tests/util/$(DEPDIR)/$(am__dirstamp)
+tests/util/xmalloc$(EXEEXT): $(tests_util_xmalloc_OBJECTS) $(tests_util_xmalloc_DEPENDENCIES) tests/util/$(am__dirstamp)
+ @rm -f tests/util/xmalloc$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_util_xmalloc_OBJECTS) $(tests_util_xmalloc_LDADD) $(LIBS)
+install-dist_sbinSCRIPTS: $(dist_sbin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
+ @list='$(dist_sbin_SCRIPTS)'; test -n "$(sbindir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-dist_sbinSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_sbin_SCRIPTS)'; test -n "$(sbindir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f client/client_wallet-file.$(OBJEXT)
+ -rm -f client/client_wallet-keytab.$(OBJEXT)
+ -rm -f client/client_wallet-krb5.$(OBJEXT)
+ -rm -f client/client_wallet-remctl.$(OBJEXT)
+ -rm -f client/client_wallet-srvtab.$(OBJEXT)
+ -rm -f client/client_wallet-wallet.$(OBJEXT)
+ -rm -f portable/portable_libportable_a-dummy.$(OBJEXT)
+ -rm -f portable/portable_libportable_a-krb5-extra.$(OBJEXT)
+ -rm -f tests/portable/asprintf-t.$(OBJEXT)
+ -rm -f tests/portable/asprintf.$(OBJEXT)
+ -rm -f tests/portable/mkstemp-t.$(OBJEXT)
+ -rm -f tests/portable/mkstemp.$(OBJEXT)
+ -rm -f tests/portable/setenv-t.$(OBJEXT)
+ -rm -f tests/portable/setenv.$(OBJEXT)
+ -rm -f tests/portable/snprintf-t.$(OBJEXT)
+ -rm -f tests/portable/snprintf.$(OBJEXT)
+ -rm -f tests/portable/strlcat-t.$(OBJEXT)
+ -rm -f tests/portable/strlcat.$(OBJEXT)
+ -rm -f tests/portable/strlcpy-t.$(OBJEXT)
+ -rm -f tests/portable/strlcpy.$(OBJEXT)
+ -rm -f tests/tap/tests_tap_libtap_a-basic.$(OBJEXT)
+ -rm -f tests/tap/tests_tap_libtap_a-kerberos.$(OBJEXT)
+ -rm -f tests/tap/tests_tap_libtap_a-messages.$(OBJEXT)
+ -rm -f tests/tap/tests_tap_libtap_a-process.$(OBJEXT)
+ -rm -f tests/tests_runtests-runtests.$(OBJEXT)
+ -rm -f tests/util/concat-t.$(OBJEXT)
+ -rm -f tests/util/messages-t.$(OBJEXT)
+ -rm -f tests/util/tests_util_messages_krb5_t-messages-krb5-t.$(OBJEXT)
+ -rm -f tests/util/xmalloc.$(OBJEXT)
+ -rm -f util/util_libutil_a-concat.$(OBJEXT)
+ -rm -f util/util_libutil_a-messages-krb5.$(OBJEXT)
+ -rm -f util/util_libutil_a-messages.$(OBJEXT)
+ -rm -f util/util_libutil_a-xmalloc.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_wallet-file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_wallet-keytab.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_wallet-krb5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_wallet-remctl.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_wallet-srvtab.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_wallet-wallet.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/asprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/mkstemp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/portable_libportable_a-dummy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/portable_libportable_a-krb5-extra.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/setenv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/snprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/strlcat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/strlcpy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/tests_runtests-runtests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/asprintf-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/asprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/mkstemp-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/mkstemp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/setenv-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/setenv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/snprintf-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/snprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/strlcat-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/strlcat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/strlcpy-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/strlcpy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/tap/$(DEPDIR)/tests_tap_libtap_a-basic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/tap/$(DEPDIR)/tests_tap_libtap_a-kerberos.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/tap/$(DEPDIR)/tests_tap_libtap_a-messages.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/tap/$(DEPDIR)/tests_tap_libtap_a-process.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/util/$(DEPDIR)/concat-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/util/$(DEPDIR)/messages-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/util/$(DEPDIR)/tests_util_messages_krb5_t-messages-krb5-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/util/$(DEPDIR)/xmalloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/util_libutil_a-concat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/util_libutil_a-messages-krb5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/util_libutil_a-messages.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@util/$(DEPDIR)/util_libutil_a-xmalloc.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+portable/portable_libportable_a-dummy.o: portable/dummy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(portable_libportable_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT portable/portable_libportable_a-dummy.o -MD -MP -MF portable/$(DEPDIR)/portable_libportable_a-dummy.Tpo -c -o portable/portable_libportable_a-dummy.o `test -f 'portable/dummy.c' || echo '$(srcdir)/'`portable/dummy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) portable/$(DEPDIR)/portable_libportable_a-dummy.Tpo portable/$(DEPDIR)/portable_libportable_a-dummy.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='portable/dummy.c' object='portable/portable_libportable_a-dummy.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(portable_libportable_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o portable/portable_libportable_a-dummy.o `test -f 'portable/dummy.c' || echo '$(srcdir)/'`portable/dummy.c
+
+portable/portable_libportable_a-dummy.obj: portable/dummy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(portable_libportable_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT portable/portable_libportable_a-dummy.obj -MD -MP -MF portable/$(DEPDIR)/portable_libportable_a-dummy.Tpo -c -o portable/portable_libportable_a-dummy.obj `if test -f 'portable/dummy.c'; then $(CYGPATH_W) 'portable/dummy.c'; else $(CYGPATH_W) '$(srcdir)/portable/dummy.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) portable/$(DEPDIR)/portable_libportable_a-dummy.Tpo portable/$(DEPDIR)/portable_libportable_a-dummy.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='portable/dummy.c' object='portable/portable_libportable_a-dummy.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(portable_libportable_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o portable/portable_libportable_a-dummy.obj `if test -f 'portable/dummy.c'; then $(CYGPATH_W) 'portable/dummy.c'; else $(CYGPATH_W) '$(srcdir)/portable/dummy.c'; fi`
+
+portable/portable_libportable_a-krb5-extra.o: portable/krb5-extra.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(portable_libportable_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT portable/portable_libportable_a-krb5-extra.o -MD -MP -MF portable/$(DEPDIR)/portable_libportable_a-krb5-extra.Tpo -c -o portable/portable_libportable_a-krb5-extra.o `test -f 'portable/krb5-extra.c' || echo '$(srcdir)/'`portable/krb5-extra.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) portable/$(DEPDIR)/portable_libportable_a-krb5-extra.Tpo portable/$(DEPDIR)/portable_libportable_a-krb5-extra.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='portable/krb5-extra.c' object='portable/portable_libportable_a-krb5-extra.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(portable_libportable_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o portable/portable_libportable_a-krb5-extra.o `test -f 'portable/krb5-extra.c' || echo '$(srcdir)/'`portable/krb5-extra.c
+
+portable/portable_libportable_a-krb5-extra.obj: portable/krb5-extra.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(portable_libportable_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT portable/portable_libportable_a-krb5-extra.obj -MD -MP -MF portable/$(DEPDIR)/portable_libportable_a-krb5-extra.Tpo -c -o portable/portable_libportable_a-krb5-extra.obj `if test -f 'portable/krb5-extra.c'; then $(CYGPATH_W) 'portable/krb5-extra.c'; else $(CYGPATH_W) '$(srcdir)/portable/krb5-extra.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) portable/$(DEPDIR)/portable_libportable_a-krb5-extra.Tpo portable/$(DEPDIR)/portable_libportable_a-krb5-extra.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='portable/krb5-extra.c' object='portable/portable_libportable_a-krb5-extra.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(portable_libportable_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o portable/portable_libportable_a-krb5-extra.obj `if test -f 'portable/krb5-extra.c'; then $(CYGPATH_W) 'portable/krb5-extra.c'; else $(CYGPATH_W) '$(srcdir)/portable/krb5-extra.c'; fi`
+
+tests/tap/tests_tap_libtap_a-basic.o: tests/tap/basic.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tap/tests_tap_libtap_a-basic.o -MD -MP -MF tests/tap/$(DEPDIR)/tests_tap_libtap_a-basic.Tpo -c -o tests/tap/tests_tap_libtap_a-basic.o `test -f 'tests/tap/basic.c' || echo '$(srcdir)/'`tests/tap/basic.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/tap/$(DEPDIR)/tests_tap_libtap_a-basic.Tpo tests/tap/$(DEPDIR)/tests_tap_libtap_a-basic.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/tap/basic.c' object='tests/tap/tests_tap_libtap_a-basic.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tap/tests_tap_libtap_a-basic.o `test -f 'tests/tap/basic.c' || echo '$(srcdir)/'`tests/tap/basic.c
+
+tests/tap/tests_tap_libtap_a-basic.obj: tests/tap/basic.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tap/tests_tap_libtap_a-basic.obj -MD -MP -MF tests/tap/$(DEPDIR)/tests_tap_libtap_a-basic.Tpo -c -o tests/tap/tests_tap_libtap_a-basic.obj `if test -f 'tests/tap/basic.c'; then $(CYGPATH_W) 'tests/tap/basic.c'; else $(CYGPATH_W) '$(srcdir)/tests/tap/basic.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/tap/$(DEPDIR)/tests_tap_libtap_a-basic.Tpo tests/tap/$(DEPDIR)/tests_tap_libtap_a-basic.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/tap/basic.c' object='tests/tap/tests_tap_libtap_a-basic.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tap/tests_tap_libtap_a-basic.obj `if test -f 'tests/tap/basic.c'; then $(CYGPATH_W) 'tests/tap/basic.c'; else $(CYGPATH_W) '$(srcdir)/tests/tap/basic.c'; fi`
+
+tests/tap/tests_tap_libtap_a-kerberos.o: tests/tap/kerberos.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tap/tests_tap_libtap_a-kerberos.o -MD -MP -MF tests/tap/$(DEPDIR)/tests_tap_libtap_a-kerberos.Tpo -c -o tests/tap/tests_tap_libtap_a-kerberos.o `test -f 'tests/tap/kerberos.c' || echo '$(srcdir)/'`tests/tap/kerberos.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/tap/$(DEPDIR)/tests_tap_libtap_a-kerberos.Tpo tests/tap/$(DEPDIR)/tests_tap_libtap_a-kerberos.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/tap/kerberos.c' object='tests/tap/tests_tap_libtap_a-kerberos.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tap/tests_tap_libtap_a-kerberos.o `test -f 'tests/tap/kerberos.c' || echo '$(srcdir)/'`tests/tap/kerberos.c
+
+tests/tap/tests_tap_libtap_a-kerberos.obj: tests/tap/kerberos.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tap/tests_tap_libtap_a-kerberos.obj -MD -MP -MF tests/tap/$(DEPDIR)/tests_tap_libtap_a-kerberos.Tpo -c -o tests/tap/tests_tap_libtap_a-kerberos.obj `if test -f 'tests/tap/kerberos.c'; then $(CYGPATH_W) 'tests/tap/kerberos.c'; else $(CYGPATH_W) '$(srcdir)/tests/tap/kerberos.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/tap/$(DEPDIR)/tests_tap_libtap_a-kerberos.Tpo tests/tap/$(DEPDIR)/tests_tap_libtap_a-kerberos.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/tap/kerberos.c' object='tests/tap/tests_tap_libtap_a-kerberos.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tap/tests_tap_libtap_a-kerberos.obj `if test -f 'tests/tap/kerberos.c'; then $(CYGPATH_W) 'tests/tap/kerberos.c'; else $(CYGPATH_W) '$(srcdir)/tests/tap/kerberos.c'; fi`
+
+tests/tap/tests_tap_libtap_a-messages.o: tests/tap/messages.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tap/tests_tap_libtap_a-messages.o -MD -MP -MF tests/tap/$(DEPDIR)/tests_tap_libtap_a-messages.Tpo -c -o tests/tap/tests_tap_libtap_a-messages.o `test -f 'tests/tap/messages.c' || echo '$(srcdir)/'`tests/tap/messages.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/tap/$(DEPDIR)/tests_tap_libtap_a-messages.Tpo tests/tap/$(DEPDIR)/tests_tap_libtap_a-messages.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/tap/messages.c' object='tests/tap/tests_tap_libtap_a-messages.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tap/tests_tap_libtap_a-messages.o `test -f 'tests/tap/messages.c' || echo '$(srcdir)/'`tests/tap/messages.c
+
+tests/tap/tests_tap_libtap_a-messages.obj: tests/tap/messages.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tap/tests_tap_libtap_a-messages.obj -MD -MP -MF tests/tap/$(DEPDIR)/tests_tap_libtap_a-messages.Tpo -c -o tests/tap/tests_tap_libtap_a-messages.obj `if test -f 'tests/tap/messages.c'; then $(CYGPATH_W) 'tests/tap/messages.c'; else $(CYGPATH_W) '$(srcdir)/tests/tap/messages.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/tap/$(DEPDIR)/tests_tap_libtap_a-messages.Tpo tests/tap/$(DEPDIR)/tests_tap_libtap_a-messages.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/tap/messages.c' object='tests/tap/tests_tap_libtap_a-messages.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tap/tests_tap_libtap_a-messages.obj `if test -f 'tests/tap/messages.c'; then $(CYGPATH_W) 'tests/tap/messages.c'; else $(CYGPATH_W) '$(srcdir)/tests/tap/messages.c'; fi`
+
+tests/tap/tests_tap_libtap_a-process.o: tests/tap/process.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tap/tests_tap_libtap_a-process.o -MD -MP -MF tests/tap/$(DEPDIR)/tests_tap_libtap_a-process.Tpo -c -o tests/tap/tests_tap_libtap_a-process.o `test -f 'tests/tap/process.c' || echo '$(srcdir)/'`tests/tap/process.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/tap/$(DEPDIR)/tests_tap_libtap_a-process.Tpo tests/tap/$(DEPDIR)/tests_tap_libtap_a-process.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/tap/process.c' object='tests/tap/tests_tap_libtap_a-process.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tap/tests_tap_libtap_a-process.o `test -f 'tests/tap/process.c' || echo '$(srcdir)/'`tests/tap/process.c
+
+tests/tap/tests_tap_libtap_a-process.obj: tests/tap/process.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tap/tests_tap_libtap_a-process.obj -MD -MP -MF tests/tap/$(DEPDIR)/tests_tap_libtap_a-process.Tpo -c -o tests/tap/tests_tap_libtap_a-process.obj `if test -f 'tests/tap/process.c'; then $(CYGPATH_W) 'tests/tap/process.c'; else $(CYGPATH_W) '$(srcdir)/tests/tap/process.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/tap/$(DEPDIR)/tests_tap_libtap_a-process.Tpo tests/tap/$(DEPDIR)/tests_tap_libtap_a-process.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/tap/process.c' object='tests/tap/tests_tap_libtap_a-process.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_tap_libtap_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tap/tests_tap_libtap_a-process.obj `if test -f 'tests/tap/process.c'; then $(CYGPATH_W) 'tests/tap/process.c'; else $(CYGPATH_W) '$(srcdir)/tests/tap/process.c'; fi`
+
+util/util_libutil_a-concat.o: util/concat.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/util_libutil_a-concat.o -MD -MP -MF util/$(DEPDIR)/util_libutil_a-concat.Tpo -c -o util/util_libutil_a-concat.o `test -f 'util/concat.c' || echo '$(srcdir)/'`util/concat.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/util_libutil_a-concat.Tpo util/$(DEPDIR)/util_libutil_a-concat.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util/concat.c' object='util/util_libutil_a-concat.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/util_libutil_a-concat.o `test -f 'util/concat.c' || echo '$(srcdir)/'`util/concat.c
+
+util/util_libutil_a-concat.obj: util/concat.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/util_libutil_a-concat.obj -MD -MP -MF util/$(DEPDIR)/util_libutil_a-concat.Tpo -c -o util/util_libutil_a-concat.obj `if test -f 'util/concat.c'; then $(CYGPATH_W) 'util/concat.c'; else $(CYGPATH_W) '$(srcdir)/util/concat.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/util_libutil_a-concat.Tpo util/$(DEPDIR)/util_libutil_a-concat.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util/concat.c' object='util/util_libutil_a-concat.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/util_libutil_a-concat.obj `if test -f 'util/concat.c'; then $(CYGPATH_W) 'util/concat.c'; else $(CYGPATH_W) '$(srcdir)/util/concat.c'; fi`
+
+util/util_libutil_a-messages-krb5.o: util/messages-krb5.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/util_libutil_a-messages-krb5.o -MD -MP -MF util/$(DEPDIR)/util_libutil_a-messages-krb5.Tpo -c -o util/util_libutil_a-messages-krb5.o `test -f 'util/messages-krb5.c' || echo '$(srcdir)/'`util/messages-krb5.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/util_libutil_a-messages-krb5.Tpo util/$(DEPDIR)/util_libutil_a-messages-krb5.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util/messages-krb5.c' object='util/util_libutil_a-messages-krb5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/util_libutil_a-messages-krb5.o `test -f 'util/messages-krb5.c' || echo '$(srcdir)/'`util/messages-krb5.c
+
+util/util_libutil_a-messages-krb5.obj: util/messages-krb5.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/util_libutil_a-messages-krb5.obj -MD -MP -MF util/$(DEPDIR)/util_libutil_a-messages-krb5.Tpo -c -o util/util_libutil_a-messages-krb5.obj `if test -f 'util/messages-krb5.c'; then $(CYGPATH_W) 'util/messages-krb5.c'; else $(CYGPATH_W) '$(srcdir)/util/messages-krb5.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/util_libutil_a-messages-krb5.Tpo util/$(DEPDIR)/util_libutil_a-messages-krb5.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util/messages-krb5.c' object='util/util_libutil_a-messages-krb5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/util_libutil_a-messages-krb5.obj `if test -f 'util/messages-krb5.c'; then $(CYGPATH_W) 'util/messages-krb5.c'; else $(CYGPATH_W) '$(srcdir)/util/messages-krb5.c'; fi`
+
+util/util_libutil_a-messages.o: util/messages.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/util_libutil_a-messages.o -MD -MP -MF util/$(DEPDIR)/util_libutil_a-messages.Tpo -c -o util/util_libutil_a-messages.o `test -f 'util/messages.c' || echo '$(srcdir)/'`util/messages.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/util_libutil_a-messages.Tpo util/$(DEPDIR)/util_libutil_a-messages.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util/messages.c' object='util/util_libutil_a-messages.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/util_libutil_a-messages.o `test -f 'util/messages.c' || echo '$(srcdir)/'`util/messages.c
+
+util/util_libutil_a-messages.obj: util/messages.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/util_libutil_a-messages.obj -MD -MP -MF util/$(DEPDIR)/util_libutil_a-messages.Tpo -c -o util/util_libutil_a-messages.obj `if test -f 'util/messages.c'; then $(CYGPATH_W) 'util/messages.c'; else $(CYGPATH_W) '$(srcdir)/util/messages.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/util_libutil_a-messages.Tpo util/$(DEPDIR)/util_libutil_a-messages.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util/messages.c' object='util/util_libutil_a-messages.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/util_libutil_a-messages.obj `if test -f 'util/messages.c'; then $(CYGPATH_W) 'util/messages.c'; else $(CYGPATH_W) '$(srcdir)/util/messages.c'; fi`
+
+util/util_libutil_a-xmalloc.o: util/xmalloc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/util_libutil_a-xmalloc.o -MD -MP -MF util/$(DEPDIR)/util_libutil_a-xmalloc.Tpo -c -o util/util_libutil_a-xmalloc.o `test -f 'util/xmalloc.c' || echo '$(srcdir)/'`util/xmalloc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/util_libutil_a-xmalloc.Tpo util/$(DEPDIR)/util_libutil_a-xmalloc.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util/xmalloc.c' object='util/util_libutil_a-xmalloc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/util_libutil_a-xmalloc.o `test -f 'util/xmalloc.c' || echo '$(srcdir)/'`util/xmalloc.c
+
+util/util_libutil_a-xmalloc.obj: util/xmalloc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT util/util_libutil_a-xmalloc.obj -MD -MP -MF util/$(DEPDIR)/util_libutil_a-xmalloc.Tpo -c -o util/util_libutil_a-xmalloc.obj `if test -f 'util/xmalloc.c'; then $(CYGPATH_W) 'util/xmalloc.c'; else $(CYGPATH_W) '$(srcdir)/util/xmalloc.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) util/$(DEPDIR)/util_libutil_a-xmalloc.Tpo util/$(DEPDIR)/util_libutil_a-xmalloc.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='util/xmalloc.c' object='util/util_libutil_a-xmalloc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(util_libutil_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o util/util_libutil_a-xmalloc.obj `if test -f 'util/xmalloc.c'; then $(CYGPATH_W) 'util/xmalloc.c'; else $(CYGPATH_W) '$(srcdir)/util/xmalloc.c'; fi`
+
+client/client_wallet-file.o: client/file.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-file.o -MD -MP -MF client/$(DEPDIR)/client_wallet-file.Tpo -c -o client/client_wallet-file.o `test -f 'client/file.c' || echo '$(srcdir)/'`client/file.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-file.Tpo client/$(DEPDIR)/client_wallet-file.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/file.c' object='client/client_wallet-file.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-file.o `test -f 'client/file.c' || echo '$(srcdir)/'`client/file.c
+
+client/client_wallet-file.obj: client/file.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-file.obj -MD -MP -MF client/$(DEPDIR)/client_wallet-file.Tpo -c -o client/client_wallet-file.obj `if test -f 'client/file.c'; then $(CYGPATH_W) 'client/file.c'; else $(CYGPATH_W) '$(srcdir)/client/file.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-file.Tpo client/$(DEPDIR)/client_wallet-file.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/file.c' object='client/client_wallet-file.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-file.obj `if test -f 'client/file.c'; then $(CYGPATH_W) 'client/file.c'; else $(CYGPATH_W) '$(srcdir)/client/file.c'; fi`
+
+client/client_wallet-keytab.o: client/keytab.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-keytab.o -MD -MP -MF client/$(DEPDIR)/client_wallet-keytab.Tpo -c -o client/client_wallet-keytab.o `test -f 'client/keytab.c' || echo '$(srcdir)/'`client/keytab.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-keytab.Tpo client/$(DEPDIR)/client_wallet-keytab.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/keytab.c' object='client/client_wallet-keytab.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-keytab.o `test -f 'client/keytab.c' || echo '$(srcdir)/'`client/keytab.c
+
+client/client_wallet-keytab.obj: client/keytab.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-keytab.obj -MD -MP -MF client/$(DEPDIR)/client_wallet-keytab.Tpo -c -o client/client_wallet-keytab.obj `if test -f 'client/keytab.c'; then $(CYGPATH_W) 'client/keytab.c'; else $(CYGPATH_W) '$(srcdir)/client/keytab.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-keytab.Tpo client/$(DEPDIR)/client_wallet-keytab.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/keytab.c' object='client/client_wallet-keytab.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-keytab.obj `if test -f 'client/keytab.c'; then $(CYGPATH_W) 'client/keytab.c'; else $(CYGPATH_W) '$(srcdir)/client/keytab.c'; fi`
+
+client/client_wallet-krb5.o: client/krb5.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-krb5.o -MD -MP -MF client/$(DEPDIR)/client_wallet-krb5.Tpo -c -o client/client_wallet-krb5.o `test -f 'client/krb5.c' || echo '$(srcdir)/'`client/krb5.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-krb5.Tpo client/$(DEPDIR)/client_wallet-krb5.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/krb5.c' object='client/client_wallet-krb5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-krb5.o `test -f 'client/krb5.c' || echo '$(srcdir)/'`client/krb5.c
+
+client/client_wallet-krb5.obj: client/krb5.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-krb5.obj -MD -MP -MF client/$(DEPDIR)/client_wallet-krb5.Tpo -c -o client/client_wallet-krb5.obj `if test -f 'client/krb5.c'; then $(CYGPATH_W) 'client/krb5.c'; else $(CYGPATH_W) '$(srcdir)/client/krb5.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-krb5.Tpo client/$(DEPDIR)/client_wallet-krb5.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/krb5.c' object='client/client_wallet-krb5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-krb5.obj `if test -f 'client/krb5.c'; then $(CYGPATH_W) 'client/krb5.c'; else $(CYGPATH_W) '$(srcdir)/client/krb5.c'; fi`
+
+client/client_wallet-remctl.o: client/remctl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-remctl.o -MD -MP -MF client/$(DEPDIR)/client_wallet-remctl.Tpo -c -o client/client_wallet-remctl.o `test -f 'client/remctl.c' || echo '$(srcdir)/'`client/remctl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-remctl.Tpo client/$(DEPDIR)/client_wallet-remctl.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/remctl.c' object='client/client_wallet-remctl.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-remctl.o `test -f 'client/remctl.c' || echo '$(srcdir)/'`client/remctl.c
+
+client/client_wallet-remctl.obj: client/remctl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-remctl.obj -MD -MP -MF client/$(DEPDIR)/client_wallet-remctl.Tpo -c -o client/client_wallet-remctl.obj `if test -f 'client/remctl.c'; then $(CYGPATH_W) 'client/remctl.c'; else $(CYGPATH_W) '$(srcdir)/client/remctl.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-remctl.Tpo client/$(DEPDIR)/client_wallet-remctl.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/remctl.c' object='client/client_wallet-remctl.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-remctl.obj `if test -f 'client/remctl.c'; then $(CYGPATH_W) 'client/remctl.c'; else $(CYGPATH_W) '$(srcdir)/client/remctl.c'; fi`
+
+client/client_wallet-srvtab.o: client/srvtab.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-srvtab.o -MD -MP -MF client/$(DEPDIR)/client_wallet-srvtab.Tpo -c -o client/client_wallet-srvtab.o `test -f 'client/srvtab.c' || echo '$(srcdir)/'`client/srvtab.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-srvtab.Tpo client/$(DEPDIR)/client_wallet-srvtab.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/srvtab.c' object='client/client_wallet-srvtab.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-srvtab.o `test -f 'client/srvtab.c' || echo '$(srcdir)/'`client/srvtab.c
+
+client/client_wallet-srvtab.obj: client/srvtab.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-srvtab.obj -MD -MP -MF client/$(DEPDIR)/client_wallet-srvtab.Tpo -c -o client/client_wallet-srvtab.obj `if test -f 'client/srvtab.c'; then $(CYGPATH_W) 'client/srvtab.c'; else $(CYGPATH_W) '$(srcdir)/client/srvtab.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-srvtab.Tpo client/$(DEPDIR)/client_wallet-srvtab.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/srvtab.c' object='client/client_wallet-srvtab.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-srvtab.obj `if test -f 'client/srvtab.c'; then $(CYGPATH_W) 'client/srvtab.c'; else $(CYGPATH_W) '$(srcdir)/client/srvtab.c'; fi`
+
+client/client_wallet-wallet.o: client/wallet.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-wallet.o -MD -MP -MF client/$(DEPDIR)/client_wallet-wallet.Tpo -c -o client/client_wallet-wallet.o `test -f 'client/wallet.c' || echo '$(srcdir)/'`client/wallet.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-wallet.Tpo client/$(DEPDIR)/client_wallet-wallet.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/wallet.c' object='client/client_wallet-wallet.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-wallet.o `test -f 'client/wallet.c' || echo '$(srcdir)/'`client/wallet.c
+
+client/client_wallet-wallet.obj: client/wallet.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet-wallet.obj -MD -MP -MF client/$(DEPDIR)/client_wallet-wallet.Tpo -c -o client/client_wallet-wallet.obj `if test -f 'client/wallet.c'; then $(CYGPATH_W) 'client/wallet.c'; else $(CYGPATH_W) '$(srcdir)/client/wallet.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet-wallet.Tpo client/$(DEPDIR)/client_wallet-wallet.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/wallet.c' object='client/client_wallet-wallet.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet-wallet.obj `if test -f 'client/wallet.c'; then $(CYGPATH_W) 'client/wallet.c'; else $(CYGPATH_W) '$(srcdir)/client/wallet.c'; fi`
+
+tests/tests_runtests-runtests.o: tests/runtests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_runtests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_runtests-runtests.o -MD -MP -MF tests/$(DEPDIR)/tests_runtests-runtests.Tpo -c -o tests/tests_runtests-runtests.o `test -f 'tests/runtests.c' || echo '$(srcdir)/'`tests/runtests.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_runtests-runtests.Tpo tests/$(DEPDIR)/tests_runtests-runtests.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/runtests.c' object='tests/tests_runtests-runtests.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_runtests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_runtests-runtests.o `test -f 'tests/runtests.c' || echo '$(srcdir)/'`tests/runtests.c
+
+tests/tests_runtests-runtests.obj: tests/runtests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_runtests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/tests_runtests-runtests.obj -MD -MP -MF tests/$(DEPDIR)/tests_runtests-runtests.Tpo -c -o tests/tests_runtests-runtests.obj `if test -f 'tests/runtests.c'; then $(CYGPATH_W) 'tests/runtests.c'; else $(CYGPATH_W) '$(srcdir)/tests/runtests.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/$(DEPDIR)/tests_runtests-runtests.Tpo tests/$(DEPDIR)/tests_runtests-runtests.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/runtests.c' object='tests/tests_runtests-runtests.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_runtests_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/tests_runtests-runtests.obj `if test -f 'tests/runtests.c'; then $(CYGPATH_W) 'tests/runtests.c'; else $(CYGPATH_W) '$(srcdir)/tests/runtests.c'; fi`
+
+tests/util/tests_util_messages_krb5_t-messages-krb5-t.o: tests/util/messages-krb5-t.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_util_messages_krb5_t_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/util/tests_util_messages_krb5_t-messages-krb5-t.o -MD -MP -MF tests/util/$(DEPDIR)/tests_util_messages_krb5_t-messages-krb5-t.Tpo -c -o tests/util/tests_util_messages_krb5_t-messages-krb5-t.o `test -f 'tests/util/messages-krb5-t.c' || echo '$(srcdir)/'`tests/util/messages-krb5-t.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/util/$(DEPDIR)/tests_util_messages_krb5_t-messages-krb5-t.Tpo tests/util/$(DEPDIR)/tests_util_messages_krb5_t-messages-krb5-t.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/util/messages-krb5-t.c' object='tests/util/tests_util_messages_krb5_t-messages-krb5-t.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_util_messages_krb5_t_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/util/tests_util_messages_krb5_t-messages-krb5-t.o `test -f 'tests/util/messages-krb5-t.c' || echo '$(srcdir)/'`tests/util/messages-krb5-t.c
+
+tests/util/tests_util_messages_krb5_t-messages-krb5-t.obj: tests/util/messages-krb5-t.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_util_messages_krb5_t_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tests/util/tests_util_messages_krb5_t-messages-krb5-t.obj -MD -MP -MF tests/util/$(DEPDIR)/tests_util_messages_krb5_t-messages-krb5-t.Tpo -c -o tests/util/tests_util_messages_krb5_t-messages-krb5-t.obj `if test -f 'tests/util/messages-krb5-t.c'; then $(CYGPATH_W) 'tests/util/messages-krb5-t.c'; else $(CYGPATH_W) '$(srcdir)/tests/util/messages-krb5-t.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tests/util/$(DEPDIR)/tests_util_messages_krb5_t-messages-krb5-t.Tpo tests/util/$(DEPDIR)/tests_util_messages_krb5_t-messages-krb5-t.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tests/util/messages-krb5-t.c' object='tests/util/tests_util_messages_krb5_t-messages-krb5-t.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(tests_util_messages_krb5_t_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tests/util/tests_util_messages_krb5_t-messages-krb5-t.obj `if test -f 'tests/util/messages-krb5-t.c'; then $(CYGPATH_W) 'tests/util/messages-krb5-t.c'; else $(CYGPATH_W) '$(srcdir)/tests/util/messages-krb5-t.c'; fi`
+install-man1: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ { for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ test -z "$$files" || { \
+ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; }
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ { for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ test -z "$$files" || { \
+ echo " ( cd '$(DESTDIR)$(man8dir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(man8dir)" && rm -f $$files; }
+
+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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) config.h.in $(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; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @case `sed 15q $(srcdir)/NEWS` in \
+ *"$(VERSION)"*) : ;; \
+ *) \
+ echo "NEWS not updated; not releasing" 1>&2; \
+ exit 1;; \
+ esac
+ @list='$(MANS)'; if test -n "$$list"; then \
+ list=`for p in $$list; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+ if test -n "$$list" && \
+ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
+ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
+ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+ echo " typically \`make maintainer-clean' will remove them" >&2; \
+ exit 1; \
+ else :; fi; \
+ else :; fi
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_LIBRARIES) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(SCRIPTS) $(MANS) config.h \
+ all-local
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+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:
+ -test -z "$(LIBOBJS)" || rm -f $(LIBOBJS)
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f client/$(DEPDIR)/$(am__dirstamp)
+ -rm -f client/$(am__dirstamp)
+ -rm -f portable/$(DEPDIR)/$(am__dirstamp)
+ -rm -f portable/$(am__dirstamp)
+ -rm -f tests/$(DEPDIR)/$(am__dirstamp)
+ -rm -f tests/$(am__dirstamp)
+ -rm -f tests/portable/$(DEPDIR)/$(am__dirstamp)
+ -rm -f tests/portable/$(am__dirstamp)
+ -rm -f tests/tap/$(DEPDIR)/$(am__dirstamp)
+ -rm -f tests/tap/$(am__dirstamp)
+ -rm -f tests/util/$(DEPDIR)/$(am__dirstamp)
+ -rm -f tests/util/$(am__dirstamp)
+ -rm -f util/$(DEPDIR)/$(am__dirstamp)
+ -rm -f util/$(am__dirstamp)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-checkLIBRARIES clean-checkPROGRAMS \
+ clean-generic clean-local clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf client/$(DEPDIR) portable/$(DEPDIR) tests/$(DEPDIR) tests/portable/$(DEPDIR) tests/tap/$(DEPDIR) tests/util/$(DEPDIR) util/$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-local distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-dist_sbinSCRIPTS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf client/$(DEPDIR) portable/$(DEPDIR) tests/$(DEPDIR) tests/portable/$(DEPDIR) tests/tap/$(DEPDIR) tests/util/$(DEPDIR) util/$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-dist_sbinSCRIPTS \
+ uninstall-man
+
+uninstall-man: uninstall-man1 uninstall-man8
+
+.MAKE: all check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am all-local am--refresh check check-am \
+ check-local clean clean-binPROGRAMS clean-checkLIBRARIES \
+ clean-checkPROGRAMS clean-generic clean-local \
+ clean-noinstLIBRARIES ctags dist dist-all dist-bzip2 dist-gzip \
+ dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
+ distclean distclean-compile distclean-generic distclean-hdr \
+ distclean-local distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-binPROGRAMS install-data \
+ install-data-am install-data-local install-dist_sbinSCRIPTS \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-man1 install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-binPROGRAMS uninstall-dist_sbinSCRIPTS \
+ uninstall-man uninstall-man1 uninstall-man8
+
+
+warnings:
+ $(MAKE) V=0 CFLAGS='$(WARNINGS)'
+ $(MAKE) V=0 CFLAGS='$(WARNINGS)' $(check_PROGRAMS)
+
+# Take appropriate actions in the Perl directory as well. We don't want to
+# always build the Perl directory in all-local, since otherwise Automake does
+# this for every target, which overrides some hacks we have to do for Debian
+# packaging.
+all-local: perl/blib/lib/Wallet/Config.pm
+
+perl/blib/lib/Wallet/Config.pm:
+ set -e; if [ x"$(builddir)" != x"$(srcdir)" ] ; then \
+ mkdir perl/Wallet perl/Wallet/ACL perl/Wallet/ACL/NetDB \
+ perl/Wallet/Kadmin perl/Wallet/Object perl/t perl/t/data \
+ perl/t/lib 2>/dev/null || true ; \
+ for f in $(PERL_FILES) ; do \
+ cp "$(srcdir)/$$f" "$(builddir)/$$f" ; \
+ done \
+ fi
+ cd perl && perl Makefile.PL
+ cd perl && $(MAKE)
+
+install-data-local:
+ if [ x"$(DESTDIR)" != x ] ; then \
+ cd perl && $(MAKE) install DESTDIR=$(DESTDIR)/ ; \
+ else \
+ cd perl && $(MAKE) install ; \
+ fi
+
+# ExtUtils::MakeMaker really likes moving the Makefile aside.
+clean-local:
+ [ ! -f perl/Makefile ] || ( set -e; cd perl && $(MAKE) clean )
+ cd perl && ( [ ! -f Makefile.old ] || mv Makefile.old Makefile )
+
+# Remove the files that we copy over if and only if builddir != srcdir.
+distclean-local:
+ set -e; if [ x"$(builddir)" != x"$(srcdir)" ] ; then \
+ rm -f $(PERL_FILES) ; \
+ fi
+
+check-local: $(check_PROGRAMS)
+ cd tests && ./runtests $(abs_top_srcdir)/tests/TESTS
+ @echo ''
+ cd perl && $(MAKE) test
+
+# Alas, we have to disable this check because there's no way to do an
+# uninstall from Perl.
+distuninstallcheck:
+ @:
+
+# 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 --git a/NEWS b/NEWS
index e16c630..4c8bda6 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,36 @@
User-Visible wallet Changes
-wallet 0.10 (unreleased)
+wallet 0.10 (2010-02-21)
+
+ Add support for Heimdal KDCs as well as MIT Kerberos KDCs. There is
+ now a mandatory new setting in Wallet::Config: $KEYTAB_KRBTYPE. It
+ should be set to either "MIT" or "Heimdal" depending on the Kerberos
+ KDC implementation used. The Heimdal support requires the
+ Heimdal::Kadm5 Perl module.
+
+ Remove kaserver synchronization support. It is no longer tested, and
+ retaining the code was increasing the complexity of wallet, and some
+ specific requirements (such as different realm names between kaserver
+ and Kerberos v5 and the kvno handling) were Stanford-specific. Rather
+ than using this support, AFS sites running kaserver will probably find
+ deploying Heimdal with its internal kaserver compatibility is probably
+ an easier transition approach.
+
+ Remove the kasetkey client for setting keys in an AFS kaserver.
+
+ The wallet client no longer enables kaserver synchronization when a
+ srvtab is requested with -S. Instead, it just extracts the DES key
+ from the keytab and writes it to a srvtab. It no longer forces the
+ kvno of the srvtab to 0 (a Stanford-specific action) and instead
+ preserves the kvno from the key in the keytab. This should now do the
+ right thing for sites that use a KDC that serves both Kerberos v4 and
+ Kerberos v5 from the same database.
+
+ The wallet client can now store data containing nul characters and
+ wallet-backend will accept it if passed on standard input instead of
+ as a command-line argument. See config/wallet for the new required
+ remctld configuration. Storing data containing nul characters
+ requires remctl 2.14 or later.
Correctly handle storing of data that begins with a dash and don't
parse it as an argument to wallet-backend.
@@ -8,6 +38,57 @@ wallet 0.10 (unreleased)
Fix logging in wallet-backend and the remctl configuration to not log
the data passed to store.
+ Move all reporting from Wallet::Admin to Wallet::Report and simplify
+ the method names since they're now part of a dedicated reporting
+ class. Similarly, create a new wallet-report script to wrap
+ Wallet::Report, moving all reporting commands to it from wallet-admin,
+ and simplify the commands since they're for a dedicated reporting
+ script.
+
+ Add additional reports for wallet-report: objects owned by a specific
+ ACL, objects owned by no one, objects of a specific type, objects with
+ a specific flag, objects for which a specific ACL has privileges, ACLs
+ with an entry with a given type and identifier, and ACLs with no
+ members.
+
+ Add a new owners command to wallet-report and corresponding owners()
+ method to Wallet::Report, which returns all ACL lines on owner ACLs
+ for matching objects.
+
+ Report ACL names as well as numbers in object history.
+
+ The wallet client now uses a temporary disk ticket cache when
+ obtaining tickets with the -u option rather than an in-memory cache,
+ allowing for a libremctl built against a different Kerberos
+ implementation than the wallet client. This primarily helps with
+ testing.
+
+ Update to rra-c-util 2.3:
+
+ * Use Kerberos portability layer to support Heimdal.
+ * Avoid Kerberos API calls deprecated on Heimdal.
+ * Sanity-check the results of krb5-config before proceeding.
+ * Fall back on manual probing if krb5-config results don't work.
+ * Add --with-krb5-include and --with-krb5-lib configure options.
+ * Add --with-remctl-include and --with-remctl-lib configure options.
+ * Add --with-gssapi-include and --with-gssapi-lib configure options.
+ * Don't break if the user clobbers CPPFLAGS at build time.
+ * Suppress error output from krb5-config probes.
+ * Prefer KRB5_CONFIG over a path constructed from --with-*.
+ * Update GSS-API probes for Solaris 10's native implementation.
+ * Change AC_TRY_* to AC_*_IFELSE as recommended by Autoconf.
+ * Use AC_TYPE_LONG_LONG_INT instead of AC_CHECK_TYPES([long long]).
+ * Provide a proper bool type with Sun Studio 12 on Solaris 10.
+ * Break util/util.h into separate header files per module.
+ * Update portable and util tests for C TAP Harness 1.1.
+
+ Update to C TAP Harness 1.1:
+
+ * Remove the need for Autoconf substitution in test programs.
+ * Support running a single test program with runtests -o.
+ * Properly handle test cases that are skipped in their entirety.
+ * Much improved C TAP library more closely matching Test::More.
+
wallet 0.9 (2008-04-24)
The wallet command-line client now reads the data for store from a
diff --git a/README b/README
index fa99b18..86b0ac4 100644
--- a/README
+++ b/README
@@ -1,11 +1,12 @@
- wallet release 0.9
+ wallet release 0.10
(secure data management system)
Written by Russ Allbery <rra@stanford.edu>
- Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr.
- University. This software is distributed under a BSD-style license.
- Please see the file LICENSE in the distribution for more information.
+ Copyright 2006, 2007, 2008, 2009, 2010 Board of Trustees, Leland
+ Stanford Jr. University. This software is distributed under a BSD-style
+ license. Please see the file LICENSE in the distribution for more
+ information.
This software is beta-quality and should be treated with caution. It is
currently being tested for production deployment at Stanford.
@@ -53,13 +54,6 @@ DESCRIPTION
interface to retrieve the current key if the unchanging flag is set on a
Kerberos keytab object.
- The Kerberos keytab object implementation also optionally supports
- synchronization of keys with an AFS kaserver to aid in migration from
- Kerberos v4 to Kerberos v5. Included in the wallet distribution is the
- kasetkey client, which can create, change the keys of, and delete
- principals from an AFS kaserver, authenticating from a srvtab. It is a
- partial replacement for kas or a Kerberos v4 kadmin.
-
REQUIREMENTS
The wallet client is written in C and builds against the C remctl
@@ -88,12 +82,13 @@ REQUIREMENTS
Perl module, which comes with recent versions of Perl and is available
on CPAN for older versions.
- The keytab support in the wallet server requires the kadmin client
- program be installed and currently assumes that it follows the syntax of
- the MIT Kerberos kadmin client. It also requires that the wallet server
- have a keytab for a principal with appropriate access to create, modify,
- and delete principals from the KDC (as configured in kadm5.acl on an MIT
- Kerberos KDC).
+ The keytab support in the wallet server supports either Heimdal or MIT
+ Kerberos KDCs. The Heimdal support requires the Heimdal::Kadm5 Perl
+ module. The MIT Kerberos support requires the MIT Kerberos kadmin
+ client program be installed. In either case, wallet also requires that
+ the wallet server have a keytab for a principal with appropriate access
+ to create, modify, and delete principals from the KDC (as configured in
+ kadm5.acl on an MIT Kerberos KDC).
To support the unchanging flag on keytab objects, the Net::Remctl Perl
module (shipped with remctl) must be installed on the server and the
@@ -106,11 +101,6 @@ REQUIREMENTS
to manage DNS), the Net::Remctl Perl module must be installed on the
server.
- To support synchronization with an AFS kaserver, the server must have
- the Authen::Krb5 Perl module installed. AFS kaserver synchronization
- support also requires building kasetkey, which requires AFS and Kerberos
- v4 libraries.
-
To run the test suite, you must have Perl 5.8 or later and the Perl DBI
module installed. You will also need a DBD module installed for the
database backend you want to use (currently, either DBD::SQLite or
@@ -126,14 +116,14 @@ REQUIREMENTS
user's path or in /usr/local/sbin or /usr/sbin, that test cases can run
services on and connect to ports 14373 and 14444 on 127.0.0.1, and that
kinit and kvno (which come with Kerberos) be installed and available on
- the user's path. The full test suite also requires a local keytab, a
- srvtab with ADMIN access to a test AFS kaserver, and some additional
- configuration.
+ the user's path. The full test suite also requires a local keytab and
+ some additional configuration.
- If you change the Automake files and need to regenerate Makefile.in, you
- will need Automake 1.10 or later. If you change configure.ac or any of
- the m4 files it includes and need to regenerate configure or
- config.h.in, you will need Autoconf 2.61 or later.
+ To bootstrap from a Git checkout, or if you change the Automake files
+ and need to regenerate Makefile.in, you will need Automake 1.11 or
+ later. For bootstrap or if you change configure.ac or any of the m4
+ files it includes and need to regenerate configure or config.h.in, you
+ will need Autoconf 2.64 or later.
BUILD AND INSTALLATION
@@ -143,6 +133,10 @@ BUILD AND INSTALLATION
make
make install
+ Pass --enable-silent-rules to configure for a quieter build (similar to
+ the Linux kernel). Use make warnings instead of make to build with full
+ GCC compiler warnings (requires a relatively current version of GCC).
+
The last step will probably have to be done as root. Currently, this
always installs both the client and the server.
@@ -163,9 +157,9 @@ BUILD AND INSTALLATION
If remctl was installed in a path not normally searched by your
compiler, you must specify its installation prefix to configure with the
- --with-remctl=DIR option. If the GSS-API libraries used by remctl
- aren't in a path normally searched by your compiler, you must generally
- also specify its installation prefix with the --with-gssapi=DIR option.
+ --with-remctl=DIR option, or alternately set the path to the include
+ files and libraries separately with --with-remctl-include=DIR and
+ --with-remctl-lib=DIR.
Normally, configure will use krb5-config to determine the flags to use
to compile with your Kerberos libraries. If krb5-config isn't found, it
@@ -174,9 +168,16 @@ BUILD AND INSTALLATION
path is not the one corresponding to the Kerberos libraries you want to
use or if your Kerberos libraries and includes aren't in a location
searched by default by your compiler, you need to specify
- --with-krb5=PATH:
+ --with-krb5=PATH and --with-gssapi=PATH:
- ./configure --with-krb5=/usr/pubsw
+ ./configure --with-krb5=/usr/pubsw --with-gssapi=/usr/pubsw
+
+ You can also individually set the paths to the include directory and the
+ library directory with --with-krb5-include, --with-krb5-lib,
+ --with-gssapi-include, and --with-gssapi-lib. You may need to do this
+ if Autoconf can't figure out whether to use lib, lib32, or lib64 on your
+ platform. Note that these settings aren't used if a krb5-config script
+ is found.
To specify a particular krb5-config script to use, either set the
KRB5_CONFIG environment variable or pass it to configure like:
@@ -188,18 +189,6 @@ BUILD AND INSTALLATION
./configure KRB5_CONFIG=/nonexistent
- To build with AFS kaserver synchronization support, pass --with-kaserver
- to configure. You may need to include the path to the AFS include files
- and libraries, such as:
-
- ./configure --with-kaserver=/usr/afsws
-
- The AFS kaserver support also requires Kerberos v4 libraries and tries
- to use krb5-config to find such libraries. If your Kerberos v4
- libraries aren't somewhere found by your compiler and the krb5-config
- script doesn't produce correct results, you need to specify
- --with-krb4=PATH giving the root path of the Kerberos v4 installation.
-
You can build wallet in a different directory from the source if you
wish. To do this, create a new empty directory, cd to that directory,
and then give the path to configure when running configure. Everything
@@ -232,10 +221,7 @@ TESTING
perl/t/data/README
and follow the instructions in those files to enable the full test
- suite. Note that testing the AFS kaserver requires creating a srvtab
- with ADMIN access to a running AFS kaserver; if you don't care about AFS
- kaserver synchronization, you may want to skip that part of the test
- suite configuration.
+ suite.
The test suite also requires some additional software be installed that
isn't otherwise used by the wallet. See REQUIREMENTS above for the full
@@ -244,8 +230,12 @@ TESTING
not available, but this has not yet been fully tested in all of its
possible permutations.
- If a test case fails, please run that individual test program directly
- and send me the output when reporting the problem.
+ If a test fails, you can run a single test with verbose output via:
+
+ tests/runtests -o <name-of-test>
+
+ Do this instead of running the test program directly since it will
+ ensure that necessary environment variables are set up.
CONFIGURATION
@@ -259,9 +249,8 @@ CONFIGURATION
docuemntation (with man Wallet::Config or perldoc Wallet::Config).
There are many customization options, some of which must be set. You
may also need to create a Kerberos keytab for the keytab object backend
- and give it appropriate ACLs, set up keytab-backend and its remctld
- configuration on your KDC if you want unchanging flag support, and set
- up a srvtab if you want AFS kaserver synchronization support.
+ and give it appropriate ACLs, and set up keytab-backend and its remctld
+ configuration on your KDC if you want unchanging flag support.
The wallet client supports reading configuration settings from the
system krb5.conf file. For more information, see the CONFIGURATION
@@ -283,3 +272,6 @@ THANKS
To Huaqing Zheng, Paul Pavelko, David Hoffman, and Paul Keser for their
reviews of the wallet system design and comments on design decisions and
security models.
+
+ To Jon Robertson for the refactoring of Wallet::Kadmin, Heimdal support,
+ and many of the wallet server-side reports.
diff --git a/TODO b/TODO
index 9f11867..670a1c7 100644
--- a/TODO
+++ b/TODO
@@ -1,217 +1,200 @@
wallet To-Do List
-Release 1.0:
+Client:
-* Fix case-insensitivity bug in unique keys with MySQL for objects.
+ * Handle duplicate kvnos in a newly returned keytab and an existing
+ keytab (such as when downloading an unchanging keytab and merging it
+ into an existing one) in some reasonable fashion.
-* Add POD coverage testing using Test::POD::Coverage for the server
- modules.
+ * Support removing old kvnos from a merged keytab (similar to kadmin
+ ktremove old).
-* Provide a way to get history for deleted objects and ACLs.
+ * When reading configuration from krb5.conf, we should first try to
+ determine our principal from any existing K5 ticket cache (after
+ obtaining tickets if -u was given) and extract the realm from that
+ principal, using it as the default realm when reading configuration
+ information.
-* Display ACL names rather than index numbers when displaying history of
- owner and acl_* settings.
+ * Add readline support to the wallet client to make it easier to issue
+ multiple commands.
-* Provide a way to list all objects by type, by owner (including null), or
- by all uses of an ACL.
+ * Add support for rekeying in the wallet client. Need to resolve how to
+ get a list of principals to rekey and which keytabs to work on. This
+ possibly should be a separate binary from the regular wallet client
+ binary.
-* Provide an interface to list all empty ACLs.
+ * Support authenticating with a keytab.
-* Provide an interface to find all ACLs with a particular line.
+ * Allow store data to contain nuls. Requires rewriting the command
+ processing for store to use iovecs.
-* Provide an interface to mass-change all instances of one ACL to another.
+ * When obtaining tickets in the wallet client with -u, should we get a
+ TGT as we do now or just directly obtain the service ticket we're going
+ to use for remctl?
-* Add a help function to wallet-backend listing the commands.
+Server Interface:
-* The client may not compile against Heimdal due to changes in how the
- krb5_keyblock structure is laid out, the freeing of keytab entries,
- and the use of WRFILE for keytab merging. Check and fix.
+ * Provide a way to get history for deleted objects and ACLs.
-* Rewrite the client test suite to use Perl and to make better use of
- shared code so that it can be broken into function components.
+ * Provide an interface to mass-change all instances of one ACL to another.
-* Catch exceptions on object creation in wallet-backend so that we can log
- those as well.
+ * Add a help function to wallet-backend listing the commands.
-* Error messages from ACL operations should refer to the ACLs by name
- instead of by ID.
+ * Catch exceptions on object creation in wallet-backend so that we can
+ log those as well.
-* History records should list both ACL ID and ACL name if the name is
- still found in the database.
+ * Provide a way to list all objects for which the connecting user has
+ ACLs.
-* Add the database schema version to a global table so that we can use it
- to support schema upgrades in the future.
+ * Support limiting returned history information by timestamp.
-* On upgrades, support adding new object types and ACL verifiers to the
- class tables.
+ * Add a comment field for objects that can be set by the owner.
-* Write the LDAP entitlement ACL verifier.
+ * Provide a REST implementation of the wallet server.
-* Write the PTS ACL verifier.
+ * Provide a CGI implementation of the wallet server.
-* Write a WebAuth keyring object store. It should support attributes
- saying how long to keep old keys and how far in advance to create new
- keys and update the keyring as needed on object download.
+ * Support setting flags and attributes on autocreate. In general, work
+ out a Wallet::Object::Template Perl object that I can return that
+ specifies things other than just the ACL.
-* Rename Wallet::ACL::* to Wallet::Verifier::*. Add Wallet::ACL as a
- generic interface with Wallet::ACL::Database and Wallet::ACL::List
- implementations (or some similar name) so that we can create and check
- an ACL without having to write it into the database. Redo default ACL
- creation using that functionality.
+ * Remove the hard-coded ADMIN ACL in the server with something more
+ configurable, perhaps a global ACL table or something.
-* The wallet client currently sets sync kaserver whenever writing a keytab
- to a srvtab. This is correct for sites using kaserver and wrong for
- everyone else. Remove or rethink this once Stanford's kaserver
- migration is over.
+ACLs:
-* The wallet client currently hard-codes a kvno of 0 in srvtabs, which is
- correct for how kasetkey works but probably isn't correct for people
- using Heimdal or MIT to serve both K4 and K5 from the same KDC. Rethink
- once Stanford's kaserver migration is over.
+ * Error messages from ACL operations should refer to the ACLs by name
+ instead of by ID.
-* Add a hook to enforce ACL naming standards.
+ * Write the LDAP entitlement ACL verifier.
-Future work:
+ * Write the PTS ACL verifier.
-* Provide a way to list all objects for which the connecting user has ACLs.
+ * Rename Wallet::ACL::* to Wallet::Verifier::*. Add Wallet::ACL as a
+ generic interface with Wallet::ACL::Database and Wallet::ACL::List
+ implementations (or some similar name) so that we can create and check
+ an ACL without having to write it into the database. Redo default ACL
+ creation using that functionality.
-* Write a conventions document for ACL naming, object naming, and similar
- issues.
+ * Add a hook to enforce ACL naming standards.
-* Write a future design and roadmap document to collect notes about how
- unimplemented features should be handled.
+ * Pass a reference to the object for which the ACL is interpreted to the
+ ACL API so that ACL APIs can make more complex decisions.
-* Support limiting returned history information by timestamp.
+ * Support for pattern matching in ACLs.
-* Improve the error message for Kerberos authentication failures.
+ * A group-in-groups ACL schema.
-* Handle duplicate kvnos in a newly returned keytab and an existing keytab
- (such as when downloading an unchanging keytab and merging it into an
- existing one) in some reasonable fashion.
+ * Provide an API for verifiers to syntax-check the values before an ACL
+ is set and implement syntax checking for the Krb5 verifier.
-* Support removing old kvnos from a merged keytab (similar to kadmin
- ktremove old).
+Database:
-* There is a lot of duplicate code in wallet-backend. Convert that to
- use some sort of data-driven model with argument count and flags so
- that the method calls can be written only once. Convert wallet-admin to
- use the same code.
+ * Fix case-insensitivity bug in unique keys with MySQL for objects.
-* There's a lot of code duplication in the dispatch functions in the
- Wallet::Server class. Find a way to rewrite that so that the dispatch
- doesn't duplicate the same code patterns.
+ * Add the database schema version to a global table so that we can use it
+ to support schema upgrades in the future.
-* Refactor the test suite for the wallet backend to try to reduce the
- duplicated code.
+ * On upgrades, support adding new object types and ACL verifiers to the
+ class tables.
-* Pull common test suite code into a Perl library that can be reused.
+Objects:
-* Add a function to wallet-admin to purge expired entries. Possibly also
- check expiration before allowing anyone to get or store objects.
+ * Check whether we can just drop the realm restriction on keytabs and
+ allow the name to contain the realm if the Kerberos type is Heimdal.
-* Add a comment field for objects that can be set by the owner.
+ * Write a WebAuth keyring object store. It should support attributes
+ saying how long to keep old keys and how far in advance to create new
+ keys and update the keyring as needed on object download.
-* The keytab backend currently only supports MIT Kerberos. Add support
- for Heimdal. This should probably be done by writing a separate class
- that handles the kadmin operations that can be subclassed and that
- dynamically chooses its implementation based on run-time configuration.
+ * Use the Perl Authen::Krb5::Admin module instead of rolling our own
+ kadmin code with Expect now that MIT Kerberos has made the kadmin API
+ public.
-* Use the Perl Authen::Krb5::Admin module instead of rolling our own
- kadmin code with Expect now that MIT Kerberos has made the kadmin API
- public.
+ * Implement an ssh keypair wallet object. The server can run ssh-keygen
+ to generate a public/private key pair and return both to the client,
+ which would split them apart. Used primarily for host keys. May need
+ a side table to store key types, or a naming convention.
-* When reading configuration from krb5.conf, we should first try to
- determine our principal from any existing K5 ticket cache (after
- obtaining tickets if -u was given) and extract the realm from that
- principal, using it as the default realm when reading configuration
- information.
+ * Implement an X.509 certificate object. I expect this would store the
+ public and private key as a single file in the same format that Apache
+ can read for combined public and private keys. There were requests for
+ storing the CSR, but I don't see why you'd want to do that. Start with
+ store support. The file code is mostly sufficient here, but it would
+ be nice to automatically support object expiration based on the
+ expiration time for the certificate.
-* Implement an ssh keypair wallet object. The server can run ssh-keygen
- to generate a public/private key pair and return both to the client,
- which would split them apart. Used primarily for host keys. May need a
- side table to store key types, or a naming convention.
+ * Implement an X.509 CA so that you can get certificate objects without
+ storing them first. Need to resolve naming conventions if you want to
+ run multiple CAs on the same wallet server (but why?). Should this be
+ a different type than stored certificates?
-* Implement an X.509 certificate object. I expect this would store the
- public and private key as a single file in the same format that Apache
- can read for combined public and private keys. There were requests for
- storing the CSR, but I don't see why you'd want to do that. Start with
- store support.
+Reports:
-* Implement an X.509 CA so that you can get certificate objects without
- storing them first. Need to resolve naming conventions if you want to
- run multiple CAs on the same wallet server (but why?). Should this be a
- different type than stored certificates?
+ * Make contrib/wallet-summary generic and include it in wallet-admin,
+ with additional configuration in Wallet::Config. Enhance it to report
+ on any sort of object, not just on keytabs, and to give numbers on
+ downloaded versus not downloaded objects.
-* Add details to design-api on how to write one's own ACL verifiers and
- object implementations and register them.
+Administrative Interface:
-* Add readline support to the wallet client to make it easier to issue
- multiple commands.
+ * Add a function to wallet-admin to purge expired entries. Possibly also
+ check expiration before allowing anyone to get or store objects.
-* The wallet-backend and wallet documentation share the COMMANDS section.
- Work out some means to assemble the documentation without duplicating
- content.
+Documentation:
-* Add support for rekeying in the wallet client. Need to resolve how to
- get a list of principals to rekey and which keytabs to work on. This
- possibly should be a separate binary from the regular wallet client
- binary.
+ * Write a conventions document for ACL naming, object naming, and similar
+ issues.
-* Document using the wallet system over something other than remctl.
+ * Write a future design and roadmap document to collect notes about how
+ unimplemented features should be handled.
-* Provide a REST implementation of the wallet server.
+ * Add details to design-api on how to write one's own ACL verifiers and
+ object implementations and register them.
-* Provide a CGI implementation of the wallet server.
+ * Document using the wallet system over something other than remctl.
-* Document all diagnostics for all wallet APIs.
+ * Document all diagnostics for all wallet APIs.
-* Write a test suite to scan all wallet code looking for diagnostics that
- aren't in the documentation and warn about them.
+Code Style and Cleanup:
-* The Wallet::Config class is very ugly and could use some better internal
- API to reference the variables in it.
+ * There is a lot of duplicate code in wallet-backend. Convert that to
+ use some sort of data-driven model with argument count and flags so
+ that the method calls can be written only once. Convert wallet-admin
+ to use the same code.
-* Use Class::DBI and Class::Trigger to handle the data access layer rather
- than writing SQL directly, and implement the logging requirements with
- triggers rather than explicit SQL. This may also replace
- Wallet::Schema.
+ * There's a lot of code duplication in the dispatch functions in the
+ Wallet::Server class. Find a way to rewrite that so that the dispatch
+ doesn't duplicate the same code patterns.
-* Make contrib/wallet-report generic and include it in wallet-admin, with
- additional configuration in Wallet::Config. Enhance it to report on any
- sort of object, not just on keytabs, and to give numbers on downloaded
- versus not downloaded objects.
+ * The wallet-backend and wallet documentation share the COMMANDS section.
+ Work out some means to assemble the documentation without duplicating
+ content.
-* Support setting flags and attributes on autocreate. In general, work out
- a Wallet::Object::Template Perl object that I can return that specifies
- things other than just the ACL.
+ * The Wallet::Config class is very ugly and could use some better
+ internal API to reference the variables in it.
-* Pass a reference to the object for which the ACL is interpreted to the
- ACL API so that ACL APIs can make more complex decisions.
+ * Use Class::DBI and Class::Trigger to handle the data access layer
+ rather than writing SQL directly, and implement the logging
+ requirements with triggers rather than explicit SQL. This may also
+ replace Wallet::Schema.
-* Support for pattern matching in ACLs.
+ * Consider using Class::Accessor to get rid of the scaffolding code to
+ access object data, and a Wallet::Base class to handle things like the
+ error() method common to many classes.
-* A group-in-groups ACL schema.
+Test Suite:
-* Modify Authen::Krb5 to export krb5_524_conv_principal so that I can use
- it to determine the K4 equivalent of a K5 principal name.
+ * Add POD coverage testing using Test::POD::Coverage for the server
+ modules.
-* Provide an API for verifiers to syntax-check the values before an
- ACL is set and implement syntax checking for the Krb5 verifier.
+ * Rewrite the client test suite to use Perl and to make better use of
+ shared code so that it can be broken into function components.
-* Support authenticating with a keytab.
+ * Refactor the test suite for the wallet backend to try to reduce the
+ duplicated code.
-* Allow store data to contain nuls. Requires rewriting the command
- processing for store to use iovecs.
+ * Pull common test suite code into a Perl library that can be reused.
-May or may not be good ideas:
-
-* Consider using Class::Accessor to get rid of the scaffolding code to
- access object data, and a Wallet::Base class to handle things like the
- error() method common to many classes.
-
-* Remove the hard-coded ADMIN ACL in the server with something more
- configurable, perhaps a global ACL table or something.
-
-* When obtaining tickets in the wallet client with -u, should we get a TGT
- as we do now or just directly obtain the service ticket we're going to
- use for remctl?
+ * Write a test suite to scan all wallet code looking for diagnostics that
+ aren't in the documentation and warn about them.
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..cec7d0b
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1170 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file 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.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],,
+[m4_warning([this file was generated for autoconf 2.65.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# longlong.m4 serial 13
+dnl Copyright (C) 1999-2007 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_LONG_LONG_INT if 'long long int' works.
+# This fixes a bug in Autoconf 2.61, but can be removed once we
+# assume 2.62 everywhere.
+
+# Note: If the type 'long long int' exists but is only 32 bits large
+# (as on some very old compilers), HAVE_LONG_LONG_INT will not be
+# defined. In this case you can treat 'long long int' like 'long int'.
+
+AC_DEFUN([AC_TYPE_LONG_LONG_INT],
+[
+ AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int],
+ [AC_LINK_IFELSE(
+ [_AC_TYPE_LONG_LONG_SNIPPET],
+ [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004.
+ dnl If cross compiling, assume the bug isn't important, since
+ dnl nobody cross compiles for this platform as far as we know.
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[@%:@include <limits.h>
+ @%:@ifndef LLONG_MAX
+ @%:@ define HALF \
+ (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+ @%:@ define LLONG_MAX (HALF - 1 + HALF)
+ @%:@endif]],
+ [[long long int n = 1;
+ int i;
+ for (i = 0; ; i++)
+ {
+ long long int m = n << i;
+ if (m >> i != n)
+ return 1;
+ if (LLONG_MAX / 2 < m)
+ break;
+ }
+ return 0;]])],
+ [ac_cv_type_long_long_int=yes],
+ [ac_cv_type_long_long_int=no],
+ [ac_cv_type_long_long_int=yes])],
+ [ac_cv_type_long_long_int=no])])
+ if test $ac_cv_type_long_long_int = yes; then
+ AC_DEFINE([HAVE_LONG_LONG_INT], 1,
+ [Define to 1 if the system has the type `long long int'.])
+ fi
+])
+
+# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
+# This fixes a bug in Autoconf 2.61, but can be removed once we
+# assume 2.62 everywhere.
+
+# Note: If the type 'unsigned long long int' exists but is only 32 bits
+# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
+# will not be defined. In this case you can treat 'unsigned long long int'
+# like 'unsigned long int'.
+
+AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
+[
+ AC_CACHE_CHECK([for unsigned long long int],
+ [ac_cv_type_unsigned_long_long_int],
+ [AC_LINK_IFELSE(
+ [_AC_TYPE_LONG_LONG_SNIPPET],
+ [ac_cv_type_unsigned_long_long_int=yes],
+ [ac_cv_type_unsigned_long_long_int=no])])
+ if test $ac_cv_type_unsigned_long_long_int = yes; then
+ AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1,
+ [Define to 1 if the system has the type `unsigned long long int'.])
+ fi
+])
+
+# Expands to a C program that can be used to test for simultaneous support
+# of 'long long' and 'unsigned long long'. We don't want to say that
+# 'long long' is available if 'unsigned long long' is not, or vice versa,
+# because too many programs rely on the symmetry between signed and unsigned
+# integer types (excluding 'bool').
+AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
+[
+ AC_LANG_PROGRAM(
+ [[/* Test preprocessor. */
+ #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ error in preprocessor;
+ #endif
+ #if ! (18446744073709551615ULL <= -1ull)
+ error in preprocessor;
+ #endif
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;]],
+ [[/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));]])
+])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 6
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+ [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2009 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 1
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# (`yes' being less verbose, `no' or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules],
+[ --enable-silent-rules less verbose build output (undo: `make V=1')
+ --disable-silent-rules verbose build output (undo: `make V=0')])
+case $enable_silent_rules in
+yes) AM_DEFAULT_VERBOSITY=0;;
+no) AM_DEFAULT_VERBOSITY=1;;
+*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file 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.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/gssapi.m4])
+m4_include([m4/krb5.m4])
+m4_include([m4/lib-depends.m4])
+m4_include([m4/lib-pathname.m4])
+m4_include([m4/remctl.m4])
+m4_include([m4/snprintf.m4])
+m4_include([m4/vamacros.m4])
diff --git a/autogen b/autogen
index 9564115..f7c8055 100755
--- a/autogen
+++ b/autogen
@@ -1,8 +1,23 @@
#!/bin/sh
-# $Id$
#
-# Run this shell script to bootstrap as necessary after a fresh checkout
-# from Subversion.
+# Run this shell script to bootstrap as necessary after a fresh checkout.
-autoreconf -i
+set -e
+
+autoreconf -i --force
rm -rf autom4te.cache
+
+# Generate manual pages.
+version=`grep '^wallet' NEWS | head -1 | cut -d' ' -f2`
+pod2man --release="$version" --center=wallet client/wallet.pod \
+ > client/wallet.1
+pod2man --release="$version" --center=wallet -s 8 contrib/wallet-summary \
+ > contrib/wallet-summary.8
+pod2man --release="$version" --center=wallet -s 8 server/keytab-backend \
+ > server/keytab-backend.8
+pod2man --release="$version" --center=wallet -s 8 server/wallet-admin \
+ > server/wallet-admin.8
+pod2man --release="$version" --center=wallet -s 8 server/wallet-backend \
+ > server/wallet-backend.8
+pod2man --release="$version" --center=wallet -s 8 server/wallet-report \
+ > server/wallet-report.8
diff --git a/build-aux/compile b/build-aux/compile
new file mode 100755
index 0000000..c0096a7
--- /dev/null
+++ b/build-aux/compile
@@ -0,0 +1,143 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2009-10-06.20; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software
+# Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+esac
+
+ofile=
+cfile=
+eat=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as `compile cc -o foo foo.c'.
+ # So we strip `-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no `-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # `.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/depcomp b/build-aux/depcomp
new file mode 100755
index 0000000..df8eea7
--- /dev/null
+++ b/build-aux/depcomp
@@ -0,0 +1,630 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
+# Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u="sed s,\\\\\\\\,/,g"
+ depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> "$depfile"
+ echo >> "$depfile"
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add `dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mechanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/install-sh b/build-aux/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/build-aux/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dst_arg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ -*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/missing b/build-aux/missing
new file mode 100755
index 0000000..28055d2
--- /dev/null
+++ b/build-aux/missing
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ autom4te touch the output file, or create a stub one
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program). This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+ lex*|yacc*)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ tar*)
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ exit 1
+ fi
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case $f in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te*)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison*|yacc*)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if test $# -ne 1; then
+ eval LASTARG="\${$#}"
+ case $LASTARG in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f y.tab.h; then
+ echo >y.tab.h
+ fi
+ if test ! -f y.tab.c; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex*|flex*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if test $# -ne 1; then
+ eval LASTARG="\${$#}"
+ case $LASTARG in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if test -f "$SRCFILE"; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if test ! -f lex.yy.c; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit $?
+ fi
+ ;;
+
+ makeinfo*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n "$sed_output"`
+ test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '
+ /^@setfilename/{
+ s/.* \([^ ]*\) *$/\1/
+ p
+ q
+ }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ # If the file does not exist, the user really needs makeinfo;
+ # let's fail without touching anything.
+ test -f $file || exit 1
+ touch $file
+ ;;
+
+ tar*)
+ shift
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case $firstarg in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case $firstarg in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/client/file.c b/client/file.c
index c109bd5..66d5f63 100644
--- a/client/file.c
+++ b/client/file.c
@@ -1,9 +1,8 @@
-/* $Id$
- *
+/*
* File handling for the wallet client.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+ * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
*
* See LICENSE for licensing terms.
*/
@@ -16,7 +15,9 @@
#include <sys/stat.h>
#include <client/internal.h>
-#include <util/util.h>
+#include <util/concat.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
/*
* Given a filename, some data, and a length, write that data to the given
@@ -114,14 +115,13 @@ get_file(struct remctl *r, const char *prefix, const char *type,
/*
- * Read all of a file into memory and return the contents as a newly allocated
- * string. Handles a file name of "-" to mean standard input. Dies on any
- * failure.
- *
- * This will need modification later when we want to handle nul characters.
+ * Read all of a file into memory and return the contents in newly allocated
+ * memory. Returns the size of the file contents in the second argument if
+ * it's not NULL. Handles a file name of "-" to mean standard input. Dies on
+ * any failure.
*/
-char *
-read_file(const char *name)
+void *
+read_file(const char *name, size_t *length)
{
char *contents;
size_t size, offset;
@@ -139,7 +139,7 @@ read_file(const char *name)
sysdie("cannot open file %s", name);
if (fstat(fd, &st) < 0)
sysdie("cannot stat file %s", name);
- size = st.st_size + 1;
+ size = st.st_size;
contents = xmalloc(size);
}
offset = 0;
@@ -156,8 +156,7 @@ read_file(const char *name)
offset += status;
} while (status > 0);
close(fd);
- contents[offset] = '\0';
- if (memchr(contents, '\0', offset) != NULL)
- die("cannot yet handle file data containing nul characters");
+ if (length != NULL)
+ *length = offset;
return contents;
}
diff --git a/client/internal.h b/client/internal.h
index e55f2b8..d82196c 100644
--- a/client/internal.h
+++ b/client/internal.h
@@ -1,9 +1,8 @@
-/* $Id$
- *
+/*
* Internal support functions for the wallet client.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+ * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
*
* See LICENSE for licensing terms.
*/
@@ -12,31 +11,37 @@
#define CLIENT_INTERNAL_H 1
#include <portable/macros.h>
+#include <portable/krb5.h>
-#include <krb5.h>
#include <sys/types.h>
/* Forward declarations to avoid unnecessary includes. */
struct remctl;
+struct iovec;
BEGIN_DECLS
/*
* Given a Kerberos context and a principal name, obtain Kerberos credentials
- * for that principal and store them in a memory cache for use by later
- * operations.
+ * for that principal and store them in a temporary ticket cache for use by
+ * later operations. kdestroy() then cleans up that cache.
*/
void kinit(krb5_context, const char *principal);
+void kdestroy(void);
/*
- * Given a remctl object, run a remctl command. If data is non-NULL, saves
- * the standard output from the command into data with the length in length.
- * Otherwise, prints it to standard output. Either way, prints standard error
- * output and errors to standard error and returns the exit status or 255 for
- * a remctl internal error.
+ * Given a remctl object, either a NULL-terminated array of strings or an
+ * array of iovecs and the number of elements in the array, and optional data
+ * and size output variables, run a remctl command. If data is non-NULL,
+ * saves the standard output from the command into data with the length in
+ * length. Otherwise, prints it to standard output. Either way, prints
+ * standard error output and errors to standard error and returns the exit
+ * status or 255 for a remctl internal error.
*/
int run_command(struct remctl *, const char **command, char **data,
size_t *length);
+int run_commandv(struct remctl *, const struct iovec *command, size_t count,
+ char **data, size_t *length);
/*
* Check whether an object exists using the exists wallet interface. Returns
@@ -91,12 +96,12 @@ void write_srvtab(krb5_context, const char *srvtab, const char *principal,
const char *keytab);
/*
- * Read all of a file into memory and return the contents as a newly allocated
- * string. Handles a file name of "-" to mean standard input. Dies on any
- * failure. This will need modification later when we want to handle nul
- * characters.
+ * Read all of a file into memory and return the contents in newly allocated
+ * memory. Handles a file name of "-" to mean standard input. Stores the
+ * length of the data in the second argument if it isn't NULL. Dies on any
+ * failure.
*/
-char *read_file(const char *);
+void *read_file(const char *, size_t *);
END_DECLS
diff --git a/client/keytab.c b/client/keytab.c
index eb37ec1..5f2076f 100644
--- a/client/keytab.c
+++ b/client/keytab.c
@@ -1,20 +1,22 @@
-/* $Id$
- *
+/*
* Implementation of keytab handling for the wallet client.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+ * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
*
* See LICENSE for licensing terms.
*/
#include <config.h>
+#include <portable/krb5.h>
#include <portable/system.h>
#include <remctl.h>
#include <client/internal.h>
-#include <util/util.h>
+#include <util/concat.h>
+#include <util/messages-krb5.h>
+#include <util/messages.h>
/*
@@ -48,7 +50,7 @@ merge_keytab(krb5_context ctx, const char *newfile, const char *file)
status = krb5_kt_add_entry(ctx, old, &entry);
if (status != 0)
die_krb5(ctx, status, "cannot write to keytab %s", file);
- krb5_free_keytab_entry_contents(ctx, &entry);
+ krb5_kt_free_entry(ctx, &entry);
}
if (status != KRB5_KT_END)
die_krb5(ctx, status, "error reading temporary keytab %s", newfile);
@@ -61,39 +63,6 @@ merge_keytab(krb5_context ctx, const char *newfile, const char *file)
/*
- * Configure a given keytab to be synchronized with an AFS kaserver if it
- * isn't already. Returns true on success, false on failure.
- */
-static int
-set_sync(struct remctl *r, const char *type, const char *name)
-{
- const char *command[7];
- char *data = NULL;
- size_t length = 0;
- int status;
-
- command[0] = type;
- command[1] = "getattr";
- command[2] = "keytab";
- command[3] = name;
- command[4] = "sync";
- command[5] = NULL;
- status = run_command(r, command, &data, &length);
- if (status != 0)
- return 0;
- if (data == NULL || strstr(data, "kaserver\n") == NULL) {
- command[1] = "setattr";
- command[5] = "kaserver";
- command[6] = NULL;
- status = run_command(r, command, NULL, NULL);
- if (status != 0)
- return 0;
- }
- return 1;
-}
-
-
-/*
* Given a remctl object, the Kerberos context, the name of a keytab object,
* and a file name, call the correct wallet commands to download a keytab and
* write it to that file. Returns the setatus or 255 on an internal error.
@@ -108,9 +77,6 @@ get_keytab(struct remctl *r, krb5_context ctx, const char *type,
size_t length = 0;
int status;
- if (srvtab != NULL)
- if (!set_sync(r, type, name))
- return 255;
command[0] = type;
command[1] = "get";
command[2] = "keytab";
diff --git a/client/krb5.c b/client/krb5.c
index fd600da..38172ae 100644
--- a/client/krb5.c
+++ b/client/krb5.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Kerberos support functions for the wallet client.
*
* Currently, the only function here is one to obtain a ticket cache for a
@@ -7,7 +6,7 @@
* client.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+ * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
*/
#include <config.h>
@@ -16,10 +15,8 @@
#include <krb5.h>
#include <client/internal.h>
-#include <util/util.h>
-
-/* The memory cache used for wallet authentication. */
-#define CACHE_NAME "MEMORY:wallet"
+#include <util/messages-krb5.h>
+#include <util/messages.h>
/*
@@ -33,32 +30,58 @@ kinit(krb5_context ctx, const char *principal)
krb5_principal princ;
krb5_ccache ccache;
krb5_creds creds;
- krb5_get_init_creds_opt opts;
+ krb5_get_init_creds_opt *opts;
krb5_error_code status;
+ char cache_name[] = "/tmp/krb5cc_wallet_XXXXXX";
+ int fd;
/* Obtain a TGT. */
status = krb5_parse_name(ctx, principal, &princ);
if (status != 0)
die_krb5(ctx, status, "invalid Kerberos principal %s", principal);
- krb5_get_init_creds_opt_init(&opts);
+ status = krb5_get_init_creds_opt_alloc(ctx, &opts);
+ if (status != 0)
+ die_krb5(ctx, status, "cannot allocate credential options");
+ krb5_get_init_creds_opt_set_default_flags(ctx, "wallet", princ->realm,
+ opts);
memset(&creds, 0, sizeof(creds));
status = krb5_get_init_creds_password(ctx, &creds, princ, NULL,
- krb5_prompter_posix, NULL, 0, NULL, &opts);
+ krb5_prompter_posix, NULL, 0, NULL, opts);
if (status != 0)
die_krb5(ctx, status, "authentication failed");
- /* Put the new credentials into a memory cache. */
- status = krb5_cc_resolve(ctx, CACHE_NAME, &ccache);
+ /* Put the new credentials into a ticket cache. */
+ fd = mkstemp(cache_name);
+ if (fd < 0)
+ sysdie("cannot create temporary ticket cache %s", cache_name);
+ status = krb5_cc_resolve(ctx, cache_name, &ccache);
if (status != 0)
- die_krb5(ctx, status, "cannot create cache %s", CACHE_NAME);
+ die_krb5(ctx, status, "cannot create cache %s", cache_name);
status = krb5_cc_initialize(ctx, ccache, princ);
if (status != 0)
- die_krb5(ctx, status, "cannot initialize cache %s", CACHE_NAME);
+ die_krb5(ctx, status, "cannot initialize cache %s", cache_name);
krb5_free_principal(ctx, princ);
status = krb5_cc_store_cred(ctx, ccache, &creds);
if (status != 0)
die_krb5(ctx, status, "cannot store credentials");
krb5_cc_close(ctx, ccache);
- if (putenv((char *) "KRB5CCNAME=" CACHE_NAME) != 0)
+ close(fd);
+ if (setenv("KRB5CCNAME", cache_name, 1) < 0)
sysdie("cannot set KRB5CCNAME");
}
+
+
+/*
+ * Clean up the temporary ticket cache created by kinit().
+ */
+void
+kdestroy(void)
+{
+ const char *cache;
+
+ cache = getenv("KRB5CCNAME");
+ if (cache == NULL)
+ die("cannot destroy temporary ticket cache: KRB5CCNAME is not set");
+ if (unlink(cache) < 0)
+ sysdie("cannot destroy temporary ticket cache");
+}
diff --git a/client/remctl.c b/client/remctl.c
index 8b9702a..5a541d5 100644
--- a/client/remctl.c
+++ b/client/remctl.c
@@ -1,9 +1,8 @@
-/* $Id$
- *
+/*
* remctl interface for the wallet client.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2007 Board of Trustees, Leland Stanford Jr. University
+ * Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University
*
* See LICENSE for licensing terms.
*/
@@ -14,19 +13,19 @@
#include <remctl.h>
#include <client/internal.h>
-#include <util/util.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
/*
- * Given a remctl connection and a command, run the command.
- *
- * If data is non-NULL, save the output in it and return the length in length.
- * Otherwise, send any output to stdout. Either way, send error output to
- * stderr, and return the exit status (or 255 if there is an error).
+ * Retrieve the results of a remctl command, which should be issued prior to
+ * calling this function. If data is non-NULL, save the output in it and
+ * return the length in length. Otherwise, send any output to stdout. Either
+ * way, send error output to stderr, and return the exit status (or 255 if
+ * there is an error).
*/
-int
-run_command(struct remctl *r, const char **command, char **data,
- size_t *length)
+static int
+command_results(struct remctl *r, char **data, size_t *length)
{
struct remctl_output *output;
int status = 255;
@@ -35,10 +34,6 @@ run_command(struct remctl *r, const char **command, char **data,
*data = NULL;
if (length != NULL)
*length = 0;
- if (!remctl_command(r, command)) {
- warn("%s", remctl_error(r));
- return 255;
- }
do {
output = remctl_output(r);
switch (output->type) {
@@ -74,6 +69,40 @@ run_command(struct remctl *r, const char **command, char **data,
/*
+ * Given a remctl connection and a NULL-terminated array of strings, run the
+ * command and return the results using command_results, optionally putting
+ * output into the data variable.
+ */
+int
+run_command(struct remctl *r, const char **command, char **data,
+ size_t *length)
+{
+ if (!remctl_command(r, command)) {
+ warn("%s", remctl_error(r));
+ return 255;
+ }
+ return command_results(r, data, length);
+}
+
+
+/*
+ * Given a remctl connection, an array of iovecs, and the length of the array,
+ * run the command and return the results using command_results, optionally
+ * putting output into the data variable.
+ */
+int
+run_commandv(struct remctl *r, const struct iovec *command, size_t count,
+ char **data, size_t *length)
+{
+ if (!remctl_commandv(r, command, count)) {
+ warn("%s", remctl_error(r));
+ return 255;
+ }
+ return command_results(r, data, length);
+}
+
+
+/*
* Check whether an object exists using the exists wallet interface. Returns
* true if it does, false if it doesn't, and dies on remctl errors.
*/
diff --git a/client/srvtab.c b/client/srvtab.c
index 2e4ea2d..b26e6fc 100644
--- a/client/srvtab.c
+++ b/client/srvtab.c
@@ -1,20 +1,19 @@
-/* $Id$
- *
+/*
* Implementation of srvtab handling for the wallet client.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+ * Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
*
* See LICENSE for licensing terms.
*/
#include <config.h>
+#include <portable/krb5.h>
#include <portable/system.h>
-#include <krb5.h>
-
#include <client/internal.h>
-#include <util/util.h>
+#include <util/messages-krb5.h>
+#include <util/messages.h>
#ifndef KRB5_KRB4_COMPAT
# define ANAME_SZ 40
@@ -29,10 +28,6 @@
* keytab and write it to the newly created srvtab file as a srvtab. Convert
* the principal from Kerberos v5 form to Kerberos v4 form.
*
- * We always force the kvno to 0 for the srvtab. This works with how the
- * wallet synchronizes keys with kasetkey, even though it's not particularly
- * correct.
- *
* On any failure, print an error message to standard error and then exit.
*/
void
@@ -59,8 +54,13 @@ write_srvtab(krb5_context ctx, const char *srvtab, const char *principal,
ret = krb5_kt_get_entry(ctx, kt, princ, 0, ENCTYPE_DES_CBC_CRC, &entry);
if (ret != 0)
die_krb5(ctx, ret, "error reading DES key from keytab %s", keytab);
+#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK
+ if (entry.keyblock.keyvalue.length != 8)
+ die("invalid DES key length in keytab");
+#else
if (entry.key.length != 8)
die("invalid DES key length in keytab");
+#endif
krb5_kt_close(ctx, kt);
/* Convert the principal to a Kerberos v4 principal. */
@@ -80,10 +80,14 @@ write_srvtab(krb5_context ctx, const char *srvtab, const char *principal,
strcpy(data + length, realm);
length += strlen(realm);
data[length++] = '\0';
- data[length++] = '\0';
+ data[length++] = (unsigned char) entry.vno;
+#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK
+ memcpy(data + length, entry.keyblock.keyvalue.data, 8);
+#else
memcpy(data + length, entry.key.contents, 8);
+#endif
length += 8;
- krb5_free_keytab_entry_contents(ctx, &entry);
+ krb5_kt_free_entry(ctx, &entry);
/* Write out the srvtab file. */
write_file(srvtab, data, length);
diff --git a/client/wallet.1 b/client/wallet.1
new file mode 100644
index 0000000..1b25ec9
--- /dev/null
+++ b/client/wallet.1
@@ -0,0 +1,513 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "WALLET 1"
+.TH WALLET 1 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+wallet \- Client for retrieving secure data from a central server
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBwallet\fR [\fB\-hv\fR] [\fB\-c\fR \fIcommand\fR] [\fB\-f\fR \fIfile\fR]
+ [\fB\-k\fR \fIprincipal\fR] [\fB\-p\fR \fIport\fR] [\fB\-s\fR\ \fIserver\fR]
+ [\fB\-S\fR \fIsrvtab\fR] [\fB\-u\fR \fIprincipal\fR] \fIcommand\fR [\fIarg\fR ...]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBwallet\fR is a client for the wallet system, which stores or creates
+secure information such as Kerberos keytabs, associates them with ACLs and
+other metadata, and allows clients to view and download them. This client
+provides the user interface to the wallet system for both users and wallet
+administrators.
+.PP
+The \fBwallet\fR command-line client takes a command and optional arguments
+on the command line, authenticates to the wallet server using Kerberos,
+and sends that command and arguments to server. It then reads the results
+and displays them to the user or stores them in a file. The client itself
+does not know which commands are valid and which aren't; apart from some
+special handling of particular commands, it sends all commands to the
+server to respond to appropriately. This allows additional commands to be
+added to the wallet system without changing all of the clients.
+.PP
+The primary commands of the wallet system are \f(CW\*(C`get\*(C'\fR, which retrieves some
+secure data from the wallet, \f(CW\*(C`store\*(C'\fR, which stores some secure data in
+the wallet, and \f(CW\*(C`show\*(C'\fR, which stores the metadata about an object stored
+in the wallet. Each object in the wallet has a type, which determines
+what data the object represents and may determine special handling when
+downloading or storing that object, and a name. For example, a wallet
+object for the \f(CW\*(C`host/example.com\*(C'\fR Kerberos keytab would have a type of
+\&\f(CW\*(C`keytab\*(C'\fR and a name of \f(CW\*(C`host/example.com\*(C'\fR. The meaning of the name is
+specific to each type of object.
+.PP
+Most other wallet commands besides those three are only available to
+wallet administrators. The exception is attribute commands; see
+\&\s-1ATTRIBUTES\s0. The other commands allow setting ownership and ACLs on
+objects, creating and destroying objects, creating and destroying ACLs,
+and adding and removing entries from ACLs. An \s-1ACL\s0 consists of one or more
+entries, each of which is a scheme and an identifier. A scheme specifies
+a way of checking whether a user is authorized. An identifier is some
+data specific to the scheme that specifies which users are authorized.
+For example, for the \f(CW\*(C`krb5\*(C'\fR scheme, the identifier is a principal name
+and only that principal is authorized by that \s-1ACL\s0 entry.
+.PP
+To run the wallet command-line client, you must either already have a
+Kerberos ticket or use the \fB\-u\fR option. You can obtain a Kerberos ticket
+with \fBkinit\fR and see your current Kerberos tickets with \fBklist\fR. The
+wallet client uses the remctl protocol to talk to the wallet server.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fB\-c\fR \fIcommand\fR" 4
+.IX Item "-c command"
+The command prefix (remctl type) to use. Normally this is an internal
+implementation detail and the default (\f(CW\*(C`wallet\*(C'\fR) should be fine. It may
+sometimes be useful to use a different prefix for testing a different
+version of the wallet code on the server. This option can also be set in
+\&\fIkrb5.conf\fR; see \s-1CONFIGURATION\s0 below.
+.IP "\fB\-f\fR \fIfile\fR" 4
+.IX Item "-f file"
+This flag is only used in combination with the \f(CW\*(C`get\*(C'\fR and \f(CW\*(C`store\*(C'\fR
+commands. For \f(CW\*(C`get\*(C'\fR, rather than sending the secure data to standard
+output (the default), the secure data will be stored in \fIfile\fR. For
+\&\f(CW\*(C`store\*(C'\fR, the data to be stored will be read from \fIfile\fR.
+.Sp
+With \f(CW\*(C`get\*(C'\fR, if the object being retrieved is not a keytab object, any
+current file named \fIoutput\fR is renamed to \fI\fIoutout\fI.bak\fR before the new
+file is created. \fI\fIoutout\fI.new\fR is used as a temporary file and any
+existing file with that name will be deleted.
+.Sp
+If the object being retrieved is a keytab object and the file \fIoutput\fR
+already exists, the downloaded keys will be added to the existing keytab
+file \fIoutput\fR. Old keys are not removed; you may wish to run \f(CW\*(C`kadmin
+ktremove\*(C'\fR or an equivalent later to clean up old keys. \fI\fIoutput\fI.new\fR
+is still used as a temporary file and any existing file with that name
+will be deleted.
+.IP "\fB\-k\fR \fIprincipal\fR" 4
+.IX Item "-k principal"
+The service principal of the wallet server. The default is to use the
+\&\f(CW\*(C`host\*(C'\fR principal for the wallet server. The principal chosen must match
+one of the keys in the keytab used by \fBremctld\fR on the wallet server.
+This option can also be set in \fIkrb5.conf\fR; see \s-1CONFIGURATION\s0 below.
+.IP "\fB\-h\fR" 4
+.IX Item "-h"
+Display a brief summary of options and exit. All other valid options and
+commands are ignored.
+.IP "\fB\-p\fR \fIport\fR" 4
+.IX Item "-p port"
+The port to connect to on the wallet server. The default is the default
+remctl port. This option can also be set in \fIkrb5.conf\fR; see
+\&\s-1CONFIGURATION\s0 below.
+.IP "\fB\-S\fR \fIsrvtab\fR" 4
+.IX Item "-S srvtab"
+This flag is only used in combination with the \f(CW\*(C`get\*(C'\fR command on a
+\&\f(CW\*(C`keytab\*(C'\fR object, and must be used in conjunction with the \fB\-f\fR flag.
+After the keytab is saved to the file specified by \fB\-f\fR, the \s-1DES\s0 key for
+that principal will be extracted and written as a Kerberos v4 srvtab to
+the file \fIsrvtab\fR. Any existing contents of \fIsrvtab\fR will be
+destroyed.
+.Sp
+The Kerberos v4 principal name will be generated from the Kerberos v5
+principal name using the \fIkrb5_524_conv_principal()\fR function of the
+Kerberos libraries. See its documentation for more information, but
+briefly (and in the absence of special configuration), the Kerberos v4
+principal name will be the same as the Kerberos v5 principal name except
+that the components are separated by \f(CW\*(C`.\*(C'\fR instead of \f(CW\*(C`/\*(C'\fR; the second
+component is truncated after the first \f(CW\*(C`.\*(C'\fR if the first component is one
+of the recognized host-based principals (generally \f(CW\*(C`host\*(C'\fR, \f(CW\*(C`imap\*(C'\fR,
+\&\f(CW\*(C`pop\*(C'\fR, or \f(CW\*(C`smtp\*(C'\fR); and the first component is \f(CW\*(C`rcmd\*(C'\fR if the Kerberos v5
+principal component is \f(CW\*(C`host\*(C'\fR. The principal name must not contain more
+than two components.
+.IP "\fB\-s\fR \fIserver\fR" 4
+.IX Item "-s server"
+The wallet server to connect to. The default may be set when compiling
+the wallet client. If it isn't, either \fB\-s\fR must be given or the server
+must be set in \fIkrb5.conf\fR. See \s-1CONFIGURATION\s0 below.
+.IP "\fB\-u\fR \fIprincipal\fR" 4
+.IX Item "-u principal"
+Rather than using the user's existing ticket cache for authentication,
+authenticate as \fIprincipal\fR first and use those credentials for
+authentication to the wallet server. \fBwallet\fR will prompt for the
+password for \fIprincipal\fR. Non-password authentication methods such as
+\&\s-1PKINIT\s0 aren't supported; to use those, run \fBkinit\fR first and use an
+existing ticket cache.
+.IP "\fB\-v\fR" 4
+.IX Item "-v"
+Display the version of the \fBwallet\fR client and exit. All other valid
+options and commands are ignored.
+.SH "COMMANDS"
+.IX Header "COMMANDS"
+As mentioned above, most commands are only available to wallet
+administrators. The exceptions are \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, \f(CW\*(C`show\*(C'\fR, \f(CW\*(C`destroy\*(C'\fR,
+\&\f(CW\*(C`flag clear\*(C'\fR, \f(CW\*(C`flag set\*(C'\fR, \f(CW\*(C`getattr\*(C'\fR, \f(CW\*(C`setattr\*(C'\fR, and \f(CW\*(C`history\*(C'\fR. All
+of those commands have their own ACLs except \f(CW\*(C`getattr\*(C'\fR and \f(CW\*(C`history\*(C'\fR,
+which use the \f(CW\*(C`show\*(C'\fR \s-1ACL\s0, and \f(CW\*(C`setattr\*(C'\fR, which uses the \f(CW\*(C`store\*(C'\fR \s-1ACL\s0.
+If the appropriate \s-1ACL\s0 is set, it alone is checked to see if the user has
+access. Otherwise, \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, \f(CW\*(C`show\*(C'\fR, \f(CW\*(C`getattr\*(C'\fR, \f(CW\*(C`setattr\*(C'\fR, and
+\&\f(CW\*(C`history\*(C'\fR access is permitted if the user is authorized by the owner \s-1ACL\s0
+of the object.
+.PP
+Administrators can run any command on any object or \s-1ACL\s0 except for \f(CW\*(C`get\*(C'\fR
+and \f(CW\*(C`store\*(C'\fR. For \f(CW\*(C`get\*(C'\fR and \f(CW\*(C`show\*(C'\fR, they must still be authorized by
+either the appropriate specific \s-1ACL\s0 or the owner \s-1ACL\s0.
+.PP
+If the locked flag is set on an object, no commands can be run on that
+object that change data except the \f(CW\*(C`flags\*(C'\fR commands, nor can the \f(CW\*(C`get\*(C'\fR
+command be used on that object. \f(CW\*(C`show\*(C'\fR, \f(CW\*(C`history\*(C'\fR, \f(CW\*(C`getacl\*(C'\fR,
+\&\f(CW\*(C`getattr\*(C'\fR, and \f(CW\*(C`owner\*(C'\fR or \f(CW\*(C`expires\*(C'\fR without an argument can still be
+used on that object.
+.PP
+For more information on attributes, see \s-1ATTRIBUTES\s0.
+.IP "acl add <id> <scheme> <identifier>" 4
+.IX Item "acl add <id> <scheme> <identifier>"
+Adds an entry with <scheme> and <identifier> to the \s-1ACL\s0 <id>. <id> may be
+either the name of an \s-1ACL\s0 or its numeric identifier.
+.IP "acl create <name>" 4
+.IX Item "acl create <name>"
+Create a new, empty \s-1ACL\s0 with name <name>. When setting an \s-1ACL\s0 on an
+object with a set of entries that don't match an existing \s-1ACL\s0, first
+create a new \s-1ACL\s0 with \f(CW\*(C`acl create\*(C'\fR, add the appropriate entries to it
+with \f(CW\*(C`acl add\*(C'\fR, and then set the \s-1ACL\s0 on an object with the \f(CW\*(C`owner\*(C'\fR or
+\&\f(CW\*(C`setacl\*(C'\fR commands.
+.IP "acl destroy <id>" 4
+.IX Item "acl destroy <id>"
+Destroy the \s-1ACL\s0 <id>. This \s-1ACL\s0 must no longer be referenced by any object
+or the \s-1ACL\s0 destruction will fail. The special \s-1ACL\s0 named \f(CW\*(C`ADMIN\*(C'\fR cannot
+be destroyed.
+.IP "acl history <id>" 4
+.IX Item "acl history <id>"
+Display the history of the \s-1ACL\s0 <id>. Each change to the \s-1ACL\s0 (not
+including changes to the name of the \s-1ACL\s0) will be represented by two
+lines. The first line will have a timestamp of the change followed by a
+description of the change, and the second line will give the user who made
+the change and the host from which the change was made.
+.IP "acl remove <id> <scheme> <identifier>" 4
+.IX Item "acl remove <id> <scheme> <identifier>"
+Remove the entry with <scheme> and <identifier> from the \s-1ACL\s0 <id>. <id>
+may be either the name of an \s-1ACL\s0 or its numeric identifier. The last
+entry in the special \s-1ACL\s0 \f(CW\*(C`ADMIN\*(C'\fR cannot be removed to protect against
+accidental lockout, but administrators can remove themselves from the
+\&\f(CW\*(C`ADMIN\*(C'\fR \s-1ACL\s0 and can leave only a non-functioning entry on the \s-1ACL\s0. Use
+caution when removing entries from the \f(CW\*(C`ADMIN\*(C'\fR \s-1ACL\s0.
+.IP "acl show <id>" 4
+.IX Item "acl show <id>"
+Display the name, numeric \s-1ID\s0, and entries of the \s-1ACL\s0 <id>.
+.IP "autocreate <type> <name>" 4
+.IX Item "autocreate <type> <name>"
+Create a new object of type <type> with name <name>. The user must be
+listed in the default \s-1ACL\s0 for an object with that type and name, and the
+object will be created with that default \s-1ACL\s0 set as the object owner.
+.Sp
+Normally, there's no need to run this command directly. It's
+automatically run when trying to get or store an object that doesn't
+already exist.
+.IP "check <type> <name>" 4
+.IX Item "check <type> <name>"
+Check whether an object of type <type> and name <name> already exists. If
+it does, prints \f(CW\*(C`yes\*(C'\fR; if not, prints \f(CW\*(C`no\*(C'\fR.
+.IP "create <type> <name>" 4
+.IX Item "create <type> <name>"
+Create a new object of type <type> with name <name>. With some backends,
+this will trigger creation of an entry in an external system as well.
+The new object will have no ACLs and no owner set, so usually the
+administrator will want to then set an owner with \f(CW\*(C`owner\*(C'\fR so that the
+object will be usable.
+.IP "destroy <type> <name>" 4
+.IX Item "destroy <type> <name>"
+Destroy the object identified by <type> and <name>. With some backends,
+this will trigger destruction of an object in an external system as well.
+.IP "expires <type> <name> [<expires>]" 4
+.IX Item "expires <type> <name> [<expires>]"
+If <expires> is not given, displays the current expiration of the object
+identified by <type> and <name>, or \f(CW\*(C`No expiration set\*(C'\fR if none is set.
+The expiration will be displayed in seconds since epoch.
+.Sp
+If <date> is given, sets the expiration on the object identified by <type>
+and <name> to <date> and (if given) <time>. <date> must be in the format
+\&\f(CW\*(C`YYYY\-MM\-DD\*(C'\fR and <time> in the format \f(CW\*(C`HH:MM:SS\*(C'\fR. If <date> is the empty
+string, clears the expiration of the object.
+.Sp
+Currently, the expiration of an object is not used.
+.IP "flag clear <type> <name> <flag>" 4
+.IX Item "flag clear <type> <name> <flag>"
+Clears the flag <flag> on the object identified by <type> and <name>.
+.IP "flag set <type> <name> <flag>" 4
+.IX Item "flag set <type> <name> <flag>"
+Sets the flag <flag> on the object identified by <type> and <name>.
+Recognized flags are \f(CW\*(C`locked\*(C'\fR, which prevents all further actions on that
+object until the flag is cleared, and \f(CW\*(C`unchanging\*(C'\fR, which tells the object
+backend to not generate new data on get but instead return the same data as
+previously returned. The \f(CW\*(C`unchanging\*(C'\fR flag is not meaningful for objects
+that do not generate new data on the fly.
+.IP "get <type> <name>" 4
+.IX Item "get <type> <name>"
+Prints to standard output the data associated with the object identified
+by <type> and <name>, or stores it in a file if the \fB\-f\fR option was
+given. This may trigger generation of new data and invalidate old data
+for that object depending on the object type.
+.Sp
+If an object with type <type> and name <name> does not already exist when
+this command is issued (as checked with the check interface), \fBwallet\fR
+will attempt to automatically create it (using autocreate).
+.IP "getacl <type> <name> <acl>" 4
+.IX Item "getacl <type> <name> <acl>"
+Prints the \s-1ACL\s0 <acl>, which must be one of \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, \f(CW\*(C`show\*(C'\fR,
+\&\f(CW\*(C`destroy\*(C'\fR, or \f(CW\*(C`flags\*(C'\fR, for the object identified by <type> and <name>.
+Prints \f(CW\*(C`No ACL set\*(C'\fR if that \s-1ACL\s0 isn't set on that object. Remember that
+if the \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, or \f(CW\*(C`show\*(C'\fR ACLs aren't set, authorization falls
+back to checking the owner \s-1ACL\s0. See the \f(CW\*(C`owner\*(C'\fR command for displaying
+or setting it.
+.IP "getattr <type> <name> <attr>" 4
+.IX Item "getattr <type> <name> <attr>"
+Prints the object attribute <attr> for the object identified by <type> and
+<name>. Attributes are used to store backend-specific information for a
+particular object type, and <attr> must be an attribute type known to the
+underlying object implementation. The attribute values, if any, are
+printed one per line. If the attribute is not set on this object, nothing
+is printed.
+.IP "history <type> <name>" 4
+.IX Item "history <type> <name>"
+Displays the history for the object identified by <type> and <name>.
+This human-readable output will have two lines for each action that
+changes the object, plus for any get action. The first line has the
+timestamp of the action and the action, and the second line gives the user
+who performed the action and the host from which they performed it.
+.IP "owner <type> <name> [<owner>]" 4
+.IX Item "owner <type> <name> [<owner>]"
+If <owner> is not given, displays the current owner \s-1ACL\s0 of the object
+identified by <type> and <name>, or \f(CW\*(C`No owner set\*(C'\fR if none is set. The
+result will be the name of an \s-1ACL\s0.
+.Sp
+If <owner> is given, sets the owner of the object identified by <type> and
+<name> to <owner>. If <owner> is the empty string, clears the owner of
+the object.
+.IP "setacl <type> <name> <acl> <id>" 4
+.IX Item "setacl <type> <name> <acl> <id>"
+Sets the \s-1ACL\s0 <acl>, which must be one of \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, \f(CW\*(C`show\*(C'\fR,
+\&\f(CW\*(C`destroy\*(C'\fR, or \f(CW\*(C`flags\*(C'\fR, to <id> on the object identified by <type> and
+<name>. If <id> is the empty string, clears that \s-1ACL\s0 on the object.
+.IP "setattr <type> <name> <attr> <value> [<value> ...]" 4
+.IX Item "setattr <type> <name> <attr> <value> [<value> ...]"
+Sets the object attribute <attr> for the object identified by <type> and
+<name>. Attributes are used to store backend-specific information for a
+particular object type, and <attr> must be an attribute type known to the
+underlying object implementation. To clear the attribute for this object,
+pass in a <value> of the empty string (\f(CW\*(Aq\*(Aq\fR).
+.IP "show <type> <name>" 4
+.IX Item "show <type> <name>"
+Displays the current object metadata for the object identified by <type>
+and <name>. This human-readable output will show the object type and
+name, the owner, any specific ACLs set on the object, the expiration if
+any, and the user, remote host, and time when the object was created, last
+stored, and last downloaded.
+.IP "store <type> <name> [<data>]" 4
+.IX Item "store <type> <name> [<data>]"
+Stores <data> for the object identified by <type> and <name> for later
+retrieval with \f(CW\*(C`get\*(C'\fR. Not all object types support this. If <data> is
+not specified on the command line, it will be read from the file specified
+with \fB\-f\fR (if given) or from standard input.
+.Sp
+If an object with type <type> and name <name> does not already exist when
+this command is issued (as checked with the check interface), \fBwallet\fR
+will attempt to automatically create it (using autocreate).
+.SH "ATTRIBUTES"
+.IX Header "ATTRIBUTES"
+Object attributes store additional properties and configuration
+information for objects stored in the wallet. They are displayed as part
+of the object data with \f(CW\*(C`show\*(C'\fR, retrieved with \f(CW\*(C`getattr\*(C'\fR, and set with
+\&\f(CW\*(C`setattr\*(C'\fR.
+.SS "Keytab Attributes"
+.IX Subsection "Keytab Attributes"
+Keytab objects support the following attributes:
+.IP "enctypes" 4
+.IX Item "enctypes"
+Restricts the generated keytab to a specific set of encryption types. The
+values of this attribute must be enctype strings recognized by Kerberos
+(strings like \f(CW\*(C`aes256\-cts\-hmac\-sha1\-96\*(C'\fR or \f(CW\*(C`des\-cbc\-crc\*(C'\fR). Note that
+the salt should not be included; since the salt is irrelevant for keytab
+keys, it will always be set to \f(CW\*(C`normal\*(C'\fR by the wallet.
+.Sp
+If this attribute is set, the specified enctype list will be passed to ktadd
+when \fIget()\fR is called for that keytab. If it is not set, the default set in
+the \s-1KDC\s0 will be used.
+.Sp
+This attribute is ignored if the \f(CW\*(C`unchanging\*(C'\fR flag is set on a keytab.
+Keytabs retrieved with \f(CW\*(C`unchanging\*(C'\fR set will contain all keys present in
+the \s-1KDC\s0 for that Kerberos principal and therefore may contain different
+enctypes than those requested by this attribute.
+.SH "CONFIGURATION"
+.IX Header "CONFIGURATION"
+\&\fBwallet\fR can optionally be configured in the system \fIkrb5.conf\fR. It
+will read the default \fIkrb5.conf\fR file for the Kerberos libraries with
+which it was compiled. To set an option, put the option in the
+[appdefaults] section. \fBwallet\fR will look for options either at the top
+level of the [appdefaults] section or in a subsection named \f(CW\*(C`wallet\*(C'\fR.
+For example, the following fragment of a \fIkrb5.conf\fR file would set the
+default port to 4373 and the default server to \f(CW\*(C`wallet.example.org\*(C'\fR.
+.PP
+.Vb 5
+\& [appdefaults]
+\& wallet_port = 4373
+\& wallet = {
+\& wallet_server = wallet.example.org
+\& }
+.Ve
+.PP
+The supported options are:
+.IP "wallet_principal" 4
+.IX Item "wallet_principal"
+The service principal of the wallet server. The default is to use the
+\&\f(CW\*(C`host\*(C'\fR principal for the wallet server. The principal chosen must match
+one of the keys in the keytab used by \fBremctld\fR on the wallet server.
+The \fB\-k\fR command-line option overrides this setting.
+.IP "wallet_port" 4
+.IX Item "wallet_port"
+The port to connect to on the wallet server. The default is the default
+remctl port. The \fB\-p\fR command-line option overrides this setting.
+.IP "wallet_server" 4
+.IX Item "wallet_server"
+The wallet server to connect to. The \fB\-s\fR command-line option overrides
+this setting. The default may be set when compiling the wallet client.
+If it isn't, either \fB\-s\fR must be given or this parameter must be present
+in in \fIkrb5.conf\fR.
+.IP "wallet_type" 4
+.IX Item "wallet_type"
+The command prefix (remctl type) to use. Normally this is an internal
+implementation detail and the default (\f(CW\*(C`wallet\*(C'\fR) should be fine. It may
+sometimes be useful to use a different prefix for testing a different
+version of the wallet code on the server. The \fB\-c\fR command-line option
+overrides this setting.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIkadmin\fR\|(8), \fIkinit\fR\|(1), \fIkrb5.conf\fR\|(5), \fIremctl\fR\|(1), \fIremctld\fR\|(8)
+.PP
+This program is part of the wallet system. The current version is available
+from <http://www.eyrie.org/~eagle/software/wallet/>.
+.PP
+\&\fBwallet\fR uses the remctl protocol. For more information about remctl,
+see <http://www.eyrie.org/~eagle/software/remctl/>.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>
diff --git a/client/wallet.c b/client/wallet.c
index 5ee24f5..e6d8eb9 100644
--- a/client/wallet.c
+++ b/client/wallet.c
@@ -1,23 +1,25 @@
-/* $Id$
- *
+/*
* The client program for the wallet system.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2006, 2007, 2008
+ * Copyright 2006, 2007, 2008, 2010
* Board of Trustees, Leland Stanford Jr. University
*
* See LICENSE for licensing terms.
*/
#include <config.h>
+#include <portable/krb5.h>
#include <portable/system.h>
+#include <portable/uio.h>
#include <errno.h>
-#include <krb5.h>
#include <remctl.h>
#include <client/internal.h>
-#include <util/util.h>
+#include <util/messages-krb5.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
/*
* Basic wallet behavior options set either on the command line or via
@@ -134,7 +136,8 @@ main(int argc, char *argv[])
krb5_error_code retval;
struct options options;
int option, i, status;
- const char **command;
+ struct iovec *command;
+ size_t count, length;
const char *file = NULL;
const char *srvtab = NULL;
struct remctl *r;
@@ -240,26 +243,31 @@ main(int argc, char *argv[])
status = get_file(r, options.type, argv[1], argv[2], file);
}
} else {
+ count = argc + 1;
if (strcmp(argv[0], "store") == 0) {
if (argc > 4)
die("too many arguments");
- else if (argc == 4)
- command = xmalloc(sizeof(char *) * (argc + 2));
- else
- command = xmalloc(sizeof(char *) * (argc + 3));
- } else
- command = xmalloc(sizeof(char *) * (argc + 2));
- command[0] = options.type;
- for (i = 0; i < argc; i++)
- command[i + 1] = argv[i];
+ else if (argc < 4)
+ count++;
+ }
+ command = xmalloc(sizeof(struct iovec) * count);
+ command[0].iov_base = (char *) options.type;
+ command[0].iov_len = strlen(options.type);
+ for (i = 0; i < argc; i++) {
+ command[i + 1].iov_base = argv[i];
+ command[i + 1].iov_len = strlen(argv[i]);
+ }
if (strcmp(argv[0], "store") == 0 && argc < 4) {
- command[argc + 1] = read_file(file == NULL ? "-" : file);
- command[argc + 2] = NULL;
- } else
- command[argc + 1] = NULL;
- status = run_command(r, command, NULL, NULL);
+ if (file == NULL)
+ file = "-";
+ command[argc + 1].iov_base = read_file(file, &length);
+ command[argc + 1].iov_len = length;
+ }
+ status = run_commandv(r, command, count, NULL, NULL);
}
remctl_close(r);
krb5_free_context(ctx);
+ if (options.user != NULL)
+ kdestroy();
exit(status);
}
diff --git a/client/wallet.pod b/client/wallet.pod
index 657929b..db93700 100644
--- a/client/wallet.pod
+++ b/client/wallet.pod
@@ -2,6 +2,11 @@
wallet - Client for retrieving secure data from a central server
+=for stopwords
+-hv srvtab arg keytabs metadata keytab ACL PTS kinit klist remctl PKINIT
+acl timestamp autocreate backend-specific setacl enctypes enctype ktadd
+KDC appdefaults remctld Allbery uuencode getacl backend
+
=head1 SYNOPSIS
B<wallet> [B<-hv>] [B<-c> I<command>] [B<-f> I<file>]
@@ -44,14 +49,12 @@ entries, each of which is a scheme and an identifier. A scheme specifies
a way of checking whether a user is authorized. An identifier is some
data specific to the scheme that specifies which users are authorized.
For example, for the C<krb5> scheme, the identifier is a principal name
-and only that principal is authorized by that ACL entry. For the C<pts>
-scheme, the identifier is a PTS group name, and all members of that PTS
-group are authorized by that ACL entry.
+and only that principal is authorized by that ACL entry.
-To run the wallet command-line client, you must already have a Kerberos
-ticket. You can obtain a Kerberos ticket with B<kinit> and see your
-current Kerberos tickets with B<klist>. The wallet client uses the remctl
-protocol to talk to the wallet server.
+To run the wallet command-line client, you must either already have a
+Kerberos ticket or use the B<-u> option. You can obtain a Kerberos ticket
+with B<kinit> and see your current Kerberos tickets with B<klist>. The
+wallet client uses the remctl protocol to talk to the wallet server.
=head1 OPTIONS
@@ -84,11 +87,6 @@ ktremove> or an equivalent later to clean up old keys. F<I<output>.new>
is still used as a temporary file and any existing file with that name
will be deleted.
-C<store> does not yet support nul bytes in I<file> (or in any other way of
-specifying the data to be stored). To store binary files in the wallet,
-you will need to encode them with uuencode, base64, or some similar scheme
-and then decode them after retrieval.
-
=item B<-k> I<principal>
The service principal of the wallet server. The default is to use the
@@ -114,9 +112,19 @@ C<keytab> object, and must be used in conjunction with the B<-f> flag.
After the keytab is saved to the file specified by B<-f>, the DES key for
that principal will be extracted and written as a Kerberos v4 srvtab to
the file I<srvtab>. Any existing contents of I<srvtab> will be
-destroyed. For more information on how the principal is converted to
-Kerberos v4, see the description of the B<sync> attribute under
-L<ATTRIBUTES>.
+destroyed.
+
+The Kerberos v4 principal name will be generated from the Kerberos v5
+principal name using the krb5_524_conv_principal() function of the
+Kerberos libraries. See its documentation for more information, but
+briefly (and in the absence of special configuration), the Kerberos v4
+principal name will be the same as the Kerberos v5 principal name except
+that the components are separated by C<.> instead of C</>; the second
+component is truncated after the first C<.> if the first component is one
+of the recognized host-based principals (generally C<host>, C<imap>,
+C<pop>, or C<smtp>); and the first component is C<rcmd> if the Kerberos v5
+principal component is C<host>. The principal name must not contain more
+than two components.
=item B<-s> I<server>
@@ -191,7 +199,7 @@ Display the history of the ACL <id>. Each change to the ACL (not
including changes to the name of the ACL) will be represented by two
lines. The first line will have a timestamp of the change followed by a
description of the change, and the second line will give the user who made
-the change and the host from which the change was mde.
+the change and the host from which the change was made.
=item acl remove <id> <scheme> <identifier>
@@ -336,11 +344,6 @@ retrieval with C<get>. Not all object types support this. If <data> is
not specified on the command line, it will be read from the file specified
with B<-f> (if given) or from standard input.
-Currently, the stored data must not contain nul characters and may
-therefore not be binary data. Its length is also limited by the maximum
-command line length of the operating system of the wallet server. These
-restrictions will be lifted in the future.
-
If an object with type <type> and name <name> does not already exist when
this command is issued (as checked with the check interface), B<wallet>
will attempt to automatically create it (using autocreate).
@@ -364,9 +367,9 @@ Keytab objects support the following attributes:
Restricts the generated keytab to a specific set of encryption types. The
values of this attribute must be enctype strings recognized by Kerberos
-(strings like C<aes256-cts> or C<des-cbc-crc>). Note that the salt should
-not be included; since the salt is irrelevant for keytab keys, it will
-always be set to C<normal> by the wallet.
+(strings like C<aes256-cts-hmac-sha1-96> or C<des-cbc-crc>). Note that
+the salt should not be included; since the salt is irrelevant for keytab
+keys, it will always be set to C<normal> by the wallet.
If this attribute is set, the specified enctype list will be passed to ktadd
when get() is called for that keytab. If it is not set, the default set in
@@ -377,34 +380,6 @@ Keytabs retrieved with C<unchanging> set will contain all keys present in
the KDC for that Kerberos principal and therefore may contain different
enctypes than those requested by this attribute.
-=item sync
-
-Sets the external systems to which the key of a given principal is
-synchronized. The only supported value for this attribute is C<kaserver>,
-which says to synchronize the key with an AFS Kerberos v4 kaserver.
-
-If this attribute is set on a keytab, whenever the C<get> command is run
-for that keytab, the DES key will be extracted from that keytab and set in
-the configured AFS kaserver. If the B<-S> option is given to the
-B<wallet> client, the srvtab corresponding to the keytab will be written
-to the file specified with that option. The Kerberos v4 principal name
-will be the same as the Kerberos v5 principal name except that the
-components are separated by C<.> instead of C</>; the second component is
-truncated after the first C<.> if the first component is one of C<host>,
-C<ident>, C<imap>, C<pop>, or C<smtp>; and the first component is C<rcmd>
-if the Kerberos v5 principal component is C<host>. The principal name
-must not contain more than two components.
-
-If this attribute is set, calling C<destroy> will also destroy the
-principal from the AFS kaserver, with a principal mapping determined as
-above.
-
-The realm of the srvtab defaults to the same realm as the keytab. You can
-change this by setting the v4_realm configuration option in the [realms]
-section of krb5.conf for the local realm. The keytab must be for a
-principal in the default local realm for the B<-S> option to work
-correctly.
-
=back
=head1 CONFIGURATION
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..bf4c54e
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,192 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
+/* Define if the compiler supports C99 variadic macros. */
+#undef HAVE_C99_VAMACROS
+
+/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SNPRINTF
+
+/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_VSNPRINTF
+
+/* Define to 1 if you have the <et/com_err.h> header file. */
+#undef HAVE_ET_COM_ERR_H
+
+/* Define if the compiler supports GNU-style variadic macros. */
+#undef HAVE_GNU_VAMACROS
+
+/* Define to 1 if you have the <ibm_svc/krb5_svc.h> header file. */
+#undef HAVE_IBM_SVC_KRB5_SVC_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `krb5_free_error_message' function. */
+#undef HAVE_KRB5_FREE_ERROR_MESSAGE
+
+/* Define to 1 if you have the `krb5_get_error_message' function. */
+#undef HAVE_KRB5_GET_ERROR_MESSAGE
+
+/* Define to 1 if you have the `krb5_get_error_string' function. */
+#undef HAVE_KRB5_GET_ERROR_STRING
+
+/* Define to 1 if you have the `krb5_get_err_txt' function. */
+#undef HAVE_KRB5_GET_ERR_TXT
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_alloc' function. */
+#undef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
+
+/* Define to 1 if you have the `krb5_get_init_creds_opt_set_default_flags'
+ function. */
+#undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS
+
+/* Define to 1 if `keyblock' is a member of `krb5_keytab_entry'. */
+#undef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK
+
+/* Define to 1 if you have the `krb5_kt_free_entry' function. */
+#undef HAVE_KRB5_KT_FREE_ENTRY
+
+/* Define to 1 if you have the `krb5_principal_get_realm' function. */
+#undef HAVE_KRB5_PRINCIPAL_GET_REALM
+
+/* Define to 1 if you have the `krb5_svc_get_msg' function. */
+#undef HAVE_KRB5_SVC_GET_MSG
+
+/* Define to 1 if the system has the type `long long int'. */
+#undef HAVE_LONG_LONG_INT
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mkstemp' function. */
+#undef HAVE_MKSTEMP
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if you have the `setrlimit' function. */
+#undef HAVE_SETRLIMIT
+
+/* Define if your system has a working snprintf function. */
+#undef HAVE_SNPRINTF
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlcat' function. */
+#undef HAVE_STRLCAT
+
+/* Define to 1 if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/bitypes.h> header file. */
+#undef HAVE_SYS_BITYPES_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to the full path to remctld to run remctl tests. */
+#undef PATH_REMCTLD
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to the default server port. */
+#undef WALLET_PORT
+
+/* Define to the default server host name. */
+#undef WALLET_SERVER
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
diff --git a/config/wallet b/config/wallet
index 2e0b142..06dc39d 100644
--- a/config/wallet
+++ b/config/wallet
@@ -3,5 +3,5 @@
# This is a remctld configuration fragment to run wallet-backend, which
# implements the server side of the wallet system.
-wallet store /usr/sbin/wallet-backend logmask=4 ANYUSER
+wallet store /usr/sbin/wallet-backend stdin=4 ANYUSER
wallet ALL /usr/sbin/wallet-backend ANYUSER
diff --git a/configure b/configure
new file mode 100755
index 0000000..0c7ae3d
--- /dev/null
+++ b/configure
@@ -0,0 +1,10743 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.65 for wallet 0.10.
+#
+# Report bugs to <rra@stanford.edu>.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and rra@stanford.edu
+$0: about your system, including any error possibly output
+$0: before this message. Then install a modern shell, or
+$0: manually run the script under such a shell if you do
+$0: have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='wallet'
+PACKAGE_TARNAME='wallet'
+PACKAGE_VERSION='0.10'
+PACKAGE_STRING='wallet 0.10'
+PACKAGE_BUGREPORT='rra@stanford.edu'
+PACKAGE_URL=''
+
+ac_config_libobj_dir=portable
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+REMCTLD
+LIBOBJS
+KRB5_USES_COM_ERR_FALSE
+KRB5_USES_COM_ERR_TRUE
+KRB5_LIBS
+KRB5_LDFLAGS
+KRB5_CPPFLAGS
+KRB5_CONFIG
+GSSAPI_LIBS
+GSSAPI_LDFLAGS
+GSSAPI_CPPFLAGS
+REMCTL_LIBS
+REMCTL_LDFLAGS
+REMCTL_CPPFLAGS
+RANLIB
+EGREP
+GREP
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_silent_rules
+enable_maintainer_mode
+enable_dependency_tracking
+enable_reduced_depends
+with_remctl
+with_remctl_include
+with_remctl_lib
+with_gssapi
+with_gssapi_include
+with_gssapi_lib
+with_krb5
+with_krb5_include
+with_krb5_lib
+with_wallet_server
+with_wallet_port
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+KRB5_CONFIG
+REMCTLD'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures wallet 0.10 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/wallet]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of wallet 0.10:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-silent-rules less verbose build output (undo: `make V=1')
+ --disable-silent-rules verbose build output (undo: `make V=0')
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-reduced-depends
+ Try to minimize shared library dependencies
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-remctl=DIR Location of remctl headers and libraries
+ --with-remctl-include=DIR
+ Location of remctl headers
+ --with-remctl-lib=DIR Location of remctl libraries
+ --with-gssapi=DIR Location of GSS-API headers and libraries
+ --with-gssapi-include=DIR
+ Location of GSS-API headers
+ --with-gssapi-lib=DIR Location of GSS-API libraries
+ --with-krb5=DIR Location of Kerberos v5 headers and libraries
+ --with-krb5-include=DIR Location of Kerberos v5 headers
+ --with-krb5-lib=DIR Location of Kerberos v5 libraries
+ --with-wallet-server=HOST
+ Default wallet server
+ --with-wallet-port=PORT Default wallet server port
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ KRB5_CONFIG Path to krb5-config
+ REMCTLD Path to the remctld binary
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <rra@stanford.edu>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+wallet configure 0.10
+generated by GNU Autoconf 2.65
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to rra@stanford.edu ##
+## ------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ 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 { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext 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; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# 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 { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; 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; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_member
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ 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 { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext 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; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR
+# ------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
+$as_echo_n "checking whether $2 is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $2
+ (void) $2;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext 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; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_decl
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by wallet $as_me 0.10, which was
+generated by GNU Autoconf 2.65. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_aux_dir=
+for ac_dir in build-aux "$srcdir"/build-aux; do
+ for ac_t in install-sh install.sh shtool; do
+ if test -f "$ac_dir/$ac_t"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/$ac_t -c"
+ break 2
+ fi
+ done
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+
+am__api_version='1.11'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error "ls -t appears to fail. Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if test "${ac_cv_path_mkdir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in
+yes) AM_DEFAULT_VERBOSITY=0;;
+no) AM_DEFAULT_VERBOSITY=1;;
+*) AM_DEFAULT_VERBOSITY=1;;
+esac
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='wallet'
+ VERSION='0.10'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = x""yes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+if test "x$CC" != xcc; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+ sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } &&
+ test -f conftest2.$ac_objext && { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; };
+then
+ eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+ if test "x$CC" != xcc; then
+ # Test first that cc exists at all.
+ if { ac_try='cc -c conftest.$ac_ext >&5'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+ rm -f conftest2.*
+ if { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } &&
+ test -f conftest2.$ac_objext && { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; };
+ then
+ # cc works too.
+ :
+ else
+ # cc exists but doesn't like -o.
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+ fi
+ fi
+ fi
+else
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+rra_reduced_depends=false
+# Check whether --enable-reduced-depends was given.
+if test "${enable_reduced_depends+set}" = set; then :
+ enableval=$enable_reduced_depends; if test x"$enableval" = xyes; then :
+ rra_reduced_depends=true
+fi
+fi
+
+rra_lib_arch_name=lib
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+ if test "$ac_cv_sizeof_long" -eq 4 && test -d /usr/lib32; then :
+ rra_lib_arch_name=lib32
+else
+ if test "$ac_cv_sizeof_long" -eq 8 && test -d /usr/lib64; then :
+ rra_lib_arch_name=lib64
+fi
+fi
+
+ rra_remctl_root=
+ rra_remctl_libdir=
+ rra_remctl_includedir=
+ REMCTL_CPPFLAGS=
+ REMCTL_LDFLAGS=
+ REMCTL_LIBS=
+
+
+
+
+
+# Check whether --with-remctl was given.
+if test "${with_remctl+set}" = set; then :
+ withval=$with_remctl; if test x"$withval" != xyes && test x"$withval" != xno; then :
+ rra_remctl_root="$withval"
+fi
+fi
+
+
+# Check whether --with-remctl-include was given.
+if test "${with_remctl_include+set}" = set; then :
+ withval=$with_remctl_include; if test x"$withval" != xyes && test x"$withval" != xno; then :
+ rra_remctl_includedir="$withval"
+fi
+fi
+
+
+# Check whether --with-remctl-lib was given.
+if test "${with_remctl_lib+set}" = set; then :
+ withval=$with_remctl_lib; if test x"$withval" != xyes && test x"$withval" != xno; then :
+ rra_remctl_libdir="$withval"
+fi
+fi
+
+
+ if test x"$rra_remctl_libdir" != x; then :
+ REMCTL_LDFLAGS="-L$rra_remctl_libdir"
+else
+ if test x"$rra_remctl_root" != x; then :
+
+ if test -d "$rra_remctl_root/$rra_lib_arch_name"; then :
+ if test x"" = x; then :
+ REMCTL_LDFLAGS="$REMCTL_LDFLAGS -L$rra_remctl_root/${rra_lib_arch_name}"
+else
+ REMCTL_LDFLAGS="$REMCTL_LDFLAGS -L$rra_remctl_root/${rra_lib_arch_name}/"
+fi
+else
+ if test x"" = x; then :
+ REMCTL_LDFLAGS="$REMCTL_LDFLAGS -L$rra_remctl_root/lib"
+else
+ REMCTL_LDFLAGS="$REMCTL_LDFLAGS -L$rra_remctl_root/lib/"
+fi
+fi
+ REMCTL_LDFLAGS=`echo "$REMCTL_LDFLAGS" | sed -e 's/^ *//'`
+fi
+fi
+ if test x"$rra_remctl_includedir" != x; then :
+ REMCTL_CPPFLAGS="-I$rra_remctl_includedir"
+else
+ if test x"$rra_remctl_root" != x; then :
+ if test x"$rra_remctl_root" != x/usr; then :
+ REMCTL_CPPFLAGS="-I${rra_remctl_root}/include"
+fi
+fi
+fi
+ if test x"$rra_reduced_depends" = xtrue; then :
+ REMCTL_LIBS="-lremctl"
+else
+
+ rra_gssapi_root=
+ rra_gssapi_libdir=
+ rra_gssapi_includedir=
+ GSSAPI_CPPFLAGS=
+ GSSAPI_LDFLAGS=
+ GSSAPI_LIBS=
+
+
+
+
+
+# Check whether --with-gssapi was given.
+if test "${with_gssapi+set}" = set; then :
+ withval=$with_gssapi; if test x"$withval" != xyes && test x"$withval" != xno; then :
+ rra_gssapi_root="$withval"
+fi
+fi
+
+
+# Check whether --with-gssapi-include was given.
+if test "${with_gssapi_include+set}" = set; then :
+ withval=$with_gssapi_include; if test x"$withval" != xyes && test x"$withval" != xno; then :
+ rra_gssapi_includedir="$withval"
+fi
+fi
+
+
+# Check whether --with-gssapi-lib was given.
+if test "${with_gssapi_lib+set}" = set; then :
+ withval=$with_gssapi_lib; if test x"$withval" != xyes && test x"$withval" != xno; then :
+ rra_gssapi_libdir="$withval"
+fi
+fi
+
+
+ if test x"$rra_reduced_depends" = xtrue; then :
+ if test x"$rra_gssapi_libdir" != x; then :
+ GSSAPI_LDFLAGS="-L$rra_gssapi_libdir"
+else
+ if test x"$rra_gssapi_root" != x; then :
+
+ if test -d "$rra_gssapi_root/$rra_lib_arch_name"; then :
+ if test x"" = x; then :
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/${rra_lib_arch_name}"
+else
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/${rra_lib_arch_name}/"
+fi
+else
+ if test x"" = x; then :
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/lib"
+else
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/lib/"
+fi
+fi
+ GSSAPI_LDFLAGS=`echo "$GSSAPI_LDFLAGS" | sed -e 's/^ *//'`
+fi
+fi
+ if test x"$rra_gssapi_includedir" != x; then :
+ GSSAPI_CPPFLAGS="-I$rra_gssapi_includedir"
+else
+ if test x"$rra_gssapi_root" != x; then :
+ if test x"$rra_gssapi_root" != x/usr; then :
+ GSSAPI_CPPFLAGS="-I${rra_gssapi_root}/include"
+fi
+fi
+fi
+ rra_gssapi_save_CPPFLAGS="$CPPFLAGS"
+ rra_gssapi_save_LDFLAGS="$LDFLAGS"
+ rra_gssapi_save_LIBS="$LIBS"
+ CPPFLAGS="$GSSAPI_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$GSSAPI_LDFLAGS $LDFLAGS"
+ LIBS="$GSSAPI_LIBS $LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_import_name in -lgssapi_krb5" >&5
+$as_echo_n "checking for gss_import_name in -lgssapi_krb5... " >&6; }
+if test "${ac_cv_lib_gssapi_krb5_gss_import_name+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi_krb5 $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 gss_import_name ();
+int
+main ()
+{
+return gss_import_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gssapi_krb5_gss_import_name=yes
+else
+ ac_cv_lib_gssapi_krb5_gss_import_name=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_gssapi_krb5_gss_import_name" >&5
+$as_echo "$ac_cv_lib_gssapi_krb5_gss_import_name" >&6; }
+if test "x$ac_cv_lib_gssapi_krb5_gss_import_name" = x""yes; then :
+ GSSAPI_LIBS="-lgssapi_krb5"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_import_name in -lgssapi" >&5
+$as_echo_n "checking for gss_import_name in -lgssapi... " >&6; }
+if test "${ac_cv_lib_gssapi_gss_import_name+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi $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 gss_import_name ();
+int
+main ()
+{
+return gss_import_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gssapi_gss_import_name=yes
+else
+ ac_cv_lib_gssapi_gss_import_name=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_gssapi_gss_import_name" >&5
+$as_echo "$ac_cv_lib_gssapi_gss_import_name" >&6; }
+if test "x$ac_cv_lib_gssapi_gss_import_name" = x""yes; then :
+ GSSAPI_LIBS="-lgssapi"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_import_name in -lgss" >&5
+$as_echo_n "checking for gss_import_name in -lgss... " >&6; }
+if test "${ac_cv_lib_gss_gss_import_name+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgss $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 gss_import_name ();
+int
+main ()
+{
+return gss_import_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gss_gss_import_name=yes
+else
+ ac_cv_lib_gss_gss_import_name=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_gss_gss_import_name" >&5
+$as_echo "$ac_cv_lib_gss_gss_import_name" >&6; }
+if test "x$ac_cv_lib_gss_gss_import_name" = x""yes; then :
+ GSSAPI_LIBS="-lgss"
+else
+ as_fn_error "cannot find usable GSS-API library" "$LINENO" 5
+fi
+
+fi
+
+fi
+
+else
+
+ if test x"$rra_gssapi_root" != x && test -z "$KRB5_CONFIG"; then :
+ if test -x "${rra_gssapi_root}/bin/krb5-config"; then :
+ KRB5_CONFIG="${rra_gssapi_root}/bin/krb5-config"
+fi
+else
+ # Extract the first word of "krb5-config", so it can be a program name with args.
+set dummy krb5-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_KRB5_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $KRB5_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_KRB5_CONFIG="$KRB5_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_KRB5_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+KRB5_CONFIG=$ac_cv_path_KRB5_CONFIG
+if test -n "$KRB5_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KRB5_CONFIG" >&5
+$as_echo "$KRB5_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+ if test x"$KRB5_CONFIG" != x && test -x "$KRB5_CONFIG"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gssapi support in krb5-config" >&5
+$as_echo_n "checking for gssapi support in krb5-config... " >&6; }
+if test "${rra_cv_lib_gssapi_config+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if "$KRB5_CONFIG" 2>&1 | grep gssapi >/dev/null 2>&1; then :
+ rra_cv_lib_gssapi_config=yes
+else
+ rra_cv_lib_gssapi_config=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rra_cv_lib_gssapi_config" >&5
+$as_echo "$rra_cv_lib_gssapi_config" >&6; }
+ if test "$rra_cv_lib_gssapi_config" = yes; then :
+ GSSAPI_CPPFLAGS=`"$KRB5_CONFIG" --cflags gssapi 2>/dev/null`
+ GSSAPI_LIBS=`"$KRB5_CONFIG" --libs gssapi 2>/dev/null`
+else
+ GSSAPI_CPPFLAGS=`"$KRB5_CONFIG" --cflags 2>/dev/null`
+ GSSAPI_LIBS=`"$KRB5_CONFIG" --libs 2>/dev/null`
+fi
+ GSSAPI_CPPFLAGS=`echo "$GSSAPI_CPPFLAGS" \
+ | sed 's%-I/usr/include ?%%'`
+ rra_gssapi_save_CPPFLAGS="$CPPFLAGS"
+ rra_gssapi_save_LDFLAGS="$LDFLAGS"
+ rra_gssapi_save_LIBS="$LIBS"
+ CPPFLAGS="$GSSAPI_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$GSSAPI_LDFLAGS $LDFLAGS"
+ LIBS="$GSSAPI_LIBS $LIBS"
+ ac_fn_c_check_func "$LINENO" "gss_import_name" "ac_cv_func_gss_import_name"
+if test "x$ac_cv_func_gss_import_name" = x""yes; then :
+ CPPFLAGS="$rra_gssapi_save_CPPFLAGS"
+ LDFLAGS="$rra_gssapi_save_LDFLAGS"
+ LIBS="$rra_gssapi_save_LIBS"
+else
+ CPPFLAGS="$rra_gssapi_save_CPPFLAGS"
+ LDFLAGS="$rra_gssapi_save_LDFLAGS"
+ LIBS="$rra_gssapi_save_LIBS"
+ GSSAPI_CPPFLAGS=
+ GSSAPI_LIBS=
+ if test x"$rra_gssapi_libdir" != x; then :
+ GSSAPI_LDFLAGS="-L$rra_gssapi_libdir"
+else
+ if test x"$rra_gssapi_root" != x; then :
+
+ if test -d "$rra_gssapi_root/$rra_lib_arch_name"; then :
+ if test x"" = x; then :
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/${rra_lib_arch_name}"
+else
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/${rra_lib_arch_name}/"
+fi
+else
+ if test x"" = x; then :
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/lib"
+else
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/lib/"
+fi
+fi
+ GSSAPI_LDFLAGS=`echo "$GSSAPI_LDFLAGS" | sed -e 's/^ *//'`
+fi
+fi
+ if test x"$rra_gssapi_includedir" != x; then :
+ GSSAPI_CPPFLAGS="-I$rra_gssapi_includedir"
+else
+ if test x"$rra_gssapi_root" != x; then :
+ if test x"$rra_gssapi_root" != x/usr; then :
+ GSSAPI_CPPFLAGS="-I${rra_gssapi_root}/include"
+fi
+fi
+fi
+ rra_gssapi_save_CPPFLAGS="$CPPFLAGS"
+ rra_gssapi_save_LDFLAGS="$LDFLAGS"
+ rra_gssapi_save_LIBS="$LIBS"
+ CPPFLAGS="$GSSAPI_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$GSSAPI_LDFLAGS $LDFLAGS"
+ LIBS="$GSSAPI_LIBS $LIBS"
+ rra_gssapi_extra=
+ LIBS=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_search" >&5
+$as_echo_n "checking for library containing res_search... " >&6; }
+if test "${ac_cv_search_res_search+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 res_search ();
+int
+main ()
+{
+return res_search ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_res_search=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_res_search+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_res_search+set}" = set; then :
+
+else
+ ac_cv_search_res_search=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_res_search" >&5
+$as_echo "$ac_cv_search_res_search" >&6; }
+ac_res=$ac_cv_search_res_search
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing __res_search" >&5
+$as_echo_n "checking for library containing __res_search... " >&6; }
+if test "${ac_cv_search___res_search+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 __res_search ();
+int
+main ()
+{
+return __res_search ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search___res_search=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search___res_search+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search___res_search+set}" = set; then :
+
+else
+ ac_cv_search___res_search=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search___res_search" >&5
+$as_echo "$ac_cv_search___res_search" >&6; }
+ac_res=$ac_cv_search___res_search
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5
+$as_echo_n "checking for library containing gethostbyname... " >&6; }
+if test "${ac_cv_search_gethostbyname+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' nsl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_gethostbyname=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_gethostbyname+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_gethostbyname+set}" = set; then :
+
+else
+ ac_cv_search_gethostbyname=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5
+$as_echo "$ac_cv_search_gethostbyname" >&6; }
+ac_res=$ac_cv_search_gethostbyname
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5
+$as_echo_n "checking for library containing socket... " >&6; }
+if test "${ac_cv_search_socket+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_socket=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_socket+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_socket+set}" = set; then :
+
+else
+ ac_cv_search_socket=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5
+$as_echo "$ac_cv_search_socket" >&6; }
+ac_res=$ac_cv_search_socket
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lnsl" >&5
+$as_echo_n "checking for socket in -lnsl... " >&6; }
+if test "${ac_cv_lib_nsl_socket+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl -lsocket $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 socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_socket=yes
+else
+ ac_cv_lib_nsl_socket=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_nsl_socket" >&5
+$as_echo "$ac_cv_lib_nsl_socket" >&6; }
+if test "x$ac_cv_lib_nsl_socket" = x""yes; then :
+ LIBS="-lnsl -lsocket $LIBS"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5
+$as_echo_n "checking for library containing crypt... " >&6; }
+if test "${ac_cv_search_crypt+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 crypt ();
+int
+main ()
+{
+return crypt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' crypt; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_crypt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_crypt+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_crypt+set}" = set; then :
+
+else
+ ac_cv_search_crypt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5
+$as_echo "$ac_cv_search_crypt" >&6; }
+ac_res=$ac_cv_search_crypt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ rra_gssapi_extra="$LIBS"
+ LIBS="$rra_gssapi_save_LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_import_name in -lgssapi" >&5
+$as_echo_n "checking for gss_import_name in -lgssapi... " >&6; }
+if test "${ac_cv_lib_gssapi_gss_import_name+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi -lkrb5 -lasn1 -lroken -lcrypto -lcom_err $rra_gssapi_extra $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 gss_import_name ();
+int
+main ()
+{
+return gss_import_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gssapi_gss_import_name=yes
+else
+ ac_cv_lib_gssapi_gss_import_name=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_gssapi_gss_import_name" >&5
+$as_echo "$ac_cv_lib_gssapi_gss_import_name" >&6; }
+if test "x$ac_cv_lib_gssapi_gss_import_name" = x""yes; then :
+ GSSAPI_LIBS="-lgssapi -lkrb5 -lasn1 -lroken -lcrypto -lcom_err"
+ GSSAPI_LIBS="$GSSAPI_LIBS $rra_gssapi_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_getspecific in -lkrb5support" >&5
+$as_echo_n "checking for krb5int_getspecific in -lkrb5support... " >&6; }
+if test "${ac_cv_lib_krb5support_krb5int_getspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $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 krb5int_getspecific ();
+int
+main ()
+{
+return krb5int_getspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5support_krb5int_getspecific=yes
+else
+ ac_cv_lib_krb5support_krb5int_getspecific=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_krb5support_krb5int_getspecific" >&5
+$as_echo "$ac_cv_lib_krb5support_krb5int_getspecific" >&6; }
+if test "x$ac_cv_lib_krb5support_krb5int_getspecific" = x""yes; then :
+ rra_gssapi_extra="-lkrb5support $rra_gssapi_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setspecific in -lpthreads" >&5
+$as_echo_n "checking for pthread_setspecific in -lpthreads... " >&6; }
+if test "${ac_cv_lib_pthreads_pthread_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads $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 pthread_setspecific ();
+int
+main ()
+{
+return pthread_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthreads_pthread_setspecific=yes
+else
+ ac_cv_lib_pthreads_pthread_setspecific=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_pthreads_pthread_setspecific" >&5
+$as_echo "$ac_cv_lib_pthreads_pthread_setspecific" >&6; }
+if test "x$ac_cv_lib_pthreads_pthread_setspecific" = x""yes; then :
+ rra_gssapi_pthread="-lpthreads"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setspecific in -lpthread" >&5
+$as_echo_n "checking for pthread_setspecific in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $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 pthread_setspecific ();
+int
+main ()
+{
+return pthread_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_pthread_setspecific=yes
+else
+ ac_cv_lib_pthread_pthread_setspecific=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_pthread_pthread_setspecific" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_setspecific" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_setspecific" = x""yes; then :
+ rra_gssapi_pthread="-lpthread"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_setspecific in -lkrb5support" >&5
+$as_echo_n "checking for krb5int_setspecific in -lkrb5support... " >&6; }
+if test "${ac_cv_lib_krb5support_krb5int_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $rra_gssapi_pthread $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 krb5int_setspecific ();
+int
+main ()
+{
+return krb5int_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5support_krb5int_setspecific=yes
+else
+ ac_cv_lib_krb5support_krb5int_setspecific=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_krb5support_krb5int_setspecific" >&5
+$as_echo "$ac_cv_lib_krb5support_krb5int_setspecific" >&6; }
+if test "x$ac_cv_lib_krb5support_krb5int_setspecific" = x""yes; then :
+ rra_gssapi_extra="-lkrb5support $rra_gssapi_extra"
+ rra_gssapi_extra="$rra_gssapi_extra $rra_gssapi_pthread"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_message in -lcom_err" >&5
+$as_echo_n "checking for error_message in -lcom_err... " >&6; }
+if test "${ac_cv_lib_com_err_error_message+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcom_err $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 error_message ();
+int
+main ()
+{
+return error_message ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_com_err_error_message=yes
+else
+ ac_cv_lib_com_err_error_message=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_com_err_error_message" >&5
+$as_echo "$ac_cv_lib_com_err_error_message" >&6; }
+if test "x$ac_cv_lib_com_err_error_message" = x""yes; then :
+ rra_gssapi_extra="-lcom_err $rra_gssapi_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_hash_md5 in -lk5crypto" >&5
+$as_echo_n "checking for krb5int_hash_md5 in -lk5crypto... " >&6; }
+if test "${ac_cv_lib_k5crypto_krb5int_hash_md5+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lk5crypto $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 krb5int_hash_md5 ();
+int
+main ()
+{
+return krb5int_hash_md5 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_k5crypto_krb5int_hash_md5=yes
+else
+ ac_cv_lib_k5crypto_krb5int_hash_md5=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_k5crypto_krb5int_hash_md5" >&5
+$as_echo "$ac_cv_lib_k5crypto_krb5int_hash_md5" >&6; }
+if test "x$ac_cv_lib_k5crypto_krb5int_hash_md5" = x""yes; then :
+ rra_gssapi_extra="-lk5crypto $rra_gssapi_extra"
+fi
+
+ rra_gssapi_extra="-lkrb5 $rra_gssapi_extra"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_import_name in -lgssapi_krb5" >&5
+$as_echo_n "checking for gss_import_name in -lgssapi_krb5... " >&6; }
+if test "${ac_cv_lib_gssapi_krb5_gss_import_name+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi_krb5 $rra_gssapi_extra $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 gss_import_name ();
+int
+main ()
+{
+return gss_import_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gssapi_krb5_gss_import_name=yes
+else
+ ac_cv_lib_gssapi_krb5_gss_import_name=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_gssapi_krb5_gss_import_name" >&5
+$as_echo "$ac_cv_lib_gssapi_krb5_gss_import_name" >&6; }
+if test "x$ac_cv_lib_gssapi_krb5_gss_import_name" = x""yes; then :
+ GSSAPI_LIBS="-lgssapi_krb5 $rra_gssapi_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_import_name in -lgss" >&5
+$as_echo_n "checking for gss_import_name in -lgss... " >&6; }
+if test "${ac_cv_lib_gss_gss_import_name+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgss $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 gss_import_name ();
+int
+main ()
+{
+return gss_import_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gss_gss_import_name=yes
+else
+ ac_cv_lib_gss_gss_import_name=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_gss_gss_import_name" >&5
+$as_echo "$ac_cv_lib_gss_gss_import_name" >&6; }
+if test "x$ac_cv_lib_gss_gss_import_name" = x""yes; then :
+ GSSAPI_LIBS="-lgss"
+else
+ as_fn_error "cannot find usable GSS-API library" "$LINENO" 5
+fi
+
+fi
+
+fi
+
+ CPPFLAGS="$rra_gssapi_save_CPPFLAGS"
+ LDFLAGS="$rra_gssapi_save_LDFLAGS"
+ LIBS="$rra_gssapi_save_LIBS"
+fi
+
+else
+ if test x"$rra_gssapi_libdir" != x; then :
+ GSSAPI_LDFLAGS="-L$rra_gssapi_libdir"
+else
+ if test x"$rra_gssapi_root" != x; then :
+
+ if test -d "$rra_gssapi_root/$rra_lib_arch_name"; then :
+ if test x"" = x; then :
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/${rra_lib_arch_name}"
+else
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/${rra_lib_arch_name}/"
+fi
+else
+ if test x"" = x; then :
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/lib"
+else
+ GSSAPI_LDFLAGS="$GSSAPI_LDFLAGS -L$rra_gssapi_root/lib/"
+fi
+fi
+ GSSAPI_LDFLAGS=`echo "$GSSAPI_LDFLAGS" | sed -e 's/^ *//'`
+fi
+fi
+ if test x"$rra_gssapi_includedir" != x; then :
+ GSSAPI_CPPFLAGS="-I$rra_gssapi_includedir"
+else
+ if test x"$rra_gssapi_root" != x; then :
+ if test x"$rra_gssapi_root" != x/usr; then :
+ GSSAPI_CPPFLAGS="-I${rra_gssapi_root}/include"
+fi
+fi
+fi
+ rra_gssapi_save_CPPFLAGS="$CPPFLAGS"
+ rra_gssapi_save_LDFLAGS="$LDFLAGS"
+ rra_gssapi_save_LIBS="$LIBS"
+ CPPFLAGS="$GSSAPI_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$GSSAPI_LDFLAGS $LDFLAGS"
+ LIBS="$GSSAPI_LIBS $LIBS"
+ rra_gssapi_extra=
+ LIBS=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_search" >&5
+$as_echo_n "checking for library containing res_search... " >&6; }
+if test "${ac_cv_search_res_search+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 res_search ();
+int
+main ()
+{
+return res_search ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_res_search=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_res_search+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_res_search+set}" = set; then :
+
+else
+ ac_cv_search_res_search=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_res_search" >&5
+$as_echo "$ac_cv_search_res_search" >&6; }
+ac_res=$ac_cv_search_res_search
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing __res_search" >&5
+$as_echo_n "checking for library containing __res_search... " >&6; }
+if test "${ac_cv_search___res_search+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 __res_search ();
+int
+main ()
+{
+return __res_search ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search___res_search=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search___res_search+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search___res_search+set}" = set; then :
+
+else
+ ac_cv_search___res_search=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search___res_search" >&5
+$as_echo "$ac_cv_search___res_search" >&6; }
+ac_res=$ac_cv_search___res_search
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5
+$as_echo_n "checking for library containing gethostbyname... " >&6; }
+if test "${ac_cv_search_gethostbyname+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' nsl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_gethostbyname=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_gethostbyname+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_gethostbyname+set}" = set; then :
+
+else
+ ac_cv_search_gethostbyname=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5
+$as_echo "$ac_cv_search_gethostbyname" >&6; }
+ac_res=$ac_cv_search_gethostbyname
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5
+$as_echo_n "checking for library containing socket... " >&6; }
+if test "${ac_cv_search_socket+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_socket=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_socket+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_socket+set}" = set; then :
+
+else
+ ac_cv_search_socket=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5
+$as_echo "$ac_cv_search_socket" >&6; }
+ac_res=$ac_cv_search_socket
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lnsl" >&5
+$as_echo_n "checking for socket in -lnsl... " >&6; }
+if test "${ac_cv_lib_nsl_socket+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl -lsocket $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 socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_socket=yes
+else
+ ac_cv_lib_nsl_socket=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_nsl_socket" >&5
+$as_echo "$ac_cv_lib_nsl_socket" >&6; }
+if test "x$ac_cv_lib_nsl_socket" = x""yes; then :
+ LIBS="-lnsl -lsocket $LIBS"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5
+$as_echo_n "checking for library containing crypt... " >&6; }
+if test "${ac_cv_search_crypt+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 crypt ();
+int
+main ()
+{
+return crypt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' crypt; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_crypt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_crypt+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_crypt+set}" = set; then :
+
+else
+ ac_cv_search_crypt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5
+$as_echo "$ac_cv_search_crypt" >&6; }
+ac_res=$ac_cv_search_crypt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ rra_gssapi_extra="$LIBS"
+ LIBS="$rra_gssapi_save_LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_import_name in -lgssapi" >&5
+$as_echo_n "checking for gss_import_name in -lgssapi... " >&6; }
+if test "${ac_cv_lib_gssapi_gss_import_name+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi -lkrb5 -lasn1 -lroken -lcrypto -lcom_err $rra_gssapi_extra $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 gss_import_name ();
+int
+main ()
+{
+return gss_import_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gssapi_gss_import_name=yes
+else
+ ac_cv_lib_gssapi_gss_import_name=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_gssapi_gss_import_name" >&5
+$as_echo "$ac_cv_lib_gssapi_gss_import_name" >&6; }
+if test "x$ac_cv_lib_gssapi_gss_import_name" = x""yes; then :
+ GSSAPI_LIBS="-lgssapi -lkrb5 -lasn1 -lroken -lcrypto -lcom_err"
+ GSSAPI_LIBS="$GSSAPI_LIBS $rra_gssapi_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_getspecific in -lkrb5support" >&5
+$as_echo_n "checking for krb5int_getspecific in -lkrb5support... " >&6; }
+if test "${ac_cv_lib_krb5support_krb5int_getspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $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 krb5int_getspecific ();
+int
+main ()
+{
+return krb5int_getspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5support_krb5int_getspecific=yes
+else
+ ac_cv_lib_krb5support_krb5int_getspecific=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_krb5support_krb5int_getspecific" >&5
+$as_echo "$ac_cv_lib_krb5support_krb5int_getspecific" >&6; }
+if test "x$ac_cv_lib_krb5support_krb5int_getspecific" = x""yes; then :
+ rra_gssapi_extra="-lkrb5support $rra_gssapi_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setspecific in -lpthreads" >&5
+$as_echo_n "checking for pthread_setspecific in -lpthreads... " >&6; }
+if test "${ac_cv_lib_pthreads_pthread_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads $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 pthread_setspecific ();
+int
+main ()
+{
+return pthread_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthreads_pthread_setspecific=yes
+else
+ ac_cv_lib_pthreads_pthread_setspecific=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_pthreads_pthread_setspecific" >&5
+$as_echo "$ac_cv_lib_pthreads_pthread_setspecific" >&6; }
+if test "x$ac_cv_lib_pthreads_pthread_setspecific" = x""yes; then :
+ rra_gssapi_pthread="-lpthreads"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setspecific in -lpthread" >&5
+$as_echo_n "checking for pthread_setspecific in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $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 pthread_setspecific ();
+int
+main ()
+{
+return pthread_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_pthread_setspecific=yes
+else
+ ac_cv_lib_pthread_pthread_setspecific=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_pthread_pthread_setspecific" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_setspecific" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_setspecific" = x""yes; then :
+ rra_gssapi_pthread="-lpthread"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_setspecific in -lkrb5support" >&5
+$as_echo_n "checking for krb5int_setspecific in -lkrb5support... " >&6; }
+if test "${ac_cv_lib_krb5support_krb5int_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $rra_gssapi_pthread $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 krb5int_setspecific ();
+int
+main ()
+{
+return krb5int_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5support_krb5int_setspecific=yes
+else
+ ac_cv_lib_krb5support_krb5int_setspecific=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_krb5support_krb5int_setspecific" >&5
+$as_echo "$ac_cv_lib_krb5support_krb5int_setspecific" >&6; }
+if test "x$ac_cv_lib_krb5support_krb5int_setspecific" = x""yes; then :
+ rra_gssapi_extra="-lkrb5support $rra_gssapi_extra"
+ rra_gssapi_extra="$rra_gssapi_extra $rra_gssapi_pthread"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_message in -lcom_err" >&5
+$as_echo_n "checking for error_message in -lcom_err... " >&6; }
+if test "${ac_cv_lib_com_err_error_message+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcom_err $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 error_message ();
+int
+main ()
+{
+return error_message ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_com_err_error_message=yes
+else
+ ac_cv_lib_com_err_error_message=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_com_err_error_message" >&5
+$as_echo "$ac_cv_lib_com_err_error_message" >&6; }
+if test "x$ac_cv_lib_com_err_error_message" = x""yes; then :
+ rra_gssapi_extra="-lcom_err $rra_gssapi_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_hash_md5 in -lk5crypto" >&5
+$as_echo_n "checking for krb5int_hash_md5 in -lk5crypto... " >&6; }
+if test "${ac_cv_lib_k5crypto_krb5int_hash_md5+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lk5crypto $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 krb5int_hash_md5 ();
+int
+main ()
+{
+return krb5int_hash_md5 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_k5crypto_krb5int_hash_md5=yes
+else
+ ac_cv_lib_k5crypto_krb5int_hash_md5=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_k5crypto_krb5int_hash_md5" >&5
+$as_echo "$ac_cv_lib_k5crypto_krb5int_hash_md5" >&6; }
+if test "x$ac_cv_lib_k5crypto_krb5int_hash_md5" = x""yes; then :
+ rra_gssapi_extra="-lk5crypto $rra_gssapi_extra"
+fi
+
+ rra_gssapi_extra="-lkrb5 $rra_gssapi_extra"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_import_name in -lgssapi_krb5" >&5
+$as_echo_n "checking for gss_import_name in -lgssapi_krb5... " >&6; }
+if test "${ac_cv_lib_gssapi_krb5_gss_import_name+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi_krb5 $rra_gssapi_extra $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 gss_import_name ();
+int
+main ()
+{
+return gss_import_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gssapi_krb5_gss_import_name=yes
+else
+ ac_cv_lib_gssapi_krb5_gss_import_name=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_gssapi_krb5_gss_import_name" >&5
+$as_echo "$ac_cv_lib_gssapi_krb5_gss_import_name" >&6; }
+if test "x$ac_cv_lib_gssapi_krb5_gss_import_name" = x""yes; then :
+ GSSAPI_LIBS="-lgssapi_krb5 $rra_gssapi_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_import_name in -lgss" >&5
+$as_echo_n "checking for gss_import_name in -lgss... " >&6; }
+if test "${ac_cv_lib_gss_gss_import_name+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgss $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 gss_import_name ();
+int
+main ()
+{
+return gss_import_name ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_gss_gss_import_name=yes
+else
+ ac_cv_lib_gss_gss_import_name=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_gss_gss_import_name" >&5
+$as_echo "$ac_cv_lib_gss_gss_import_name" >&6; }
+if test "x$ac_cv_lib_gss_gss_import_name" = x""yes; then :
+ GSSAPI_LIBS="-lgss"
+else
+ as_fn_error "cannot find usable GSS-API library" "$LINENO" 5
+fi
+
+fi
+
+fi
+
+ CPPFLAGS="$rra_gssapi_save_CPPFLAGS"
+ LDFLAGS="$rra_gssapi_save_LDFLAGS"
+ LIBS="$rra_gssapi_save_LIBS"
+fi
+fi
+ REMCTL_CPPFLAGS="$REMCTL_CPPFLAGS $GSSAPI_CPPFLAGS"
+ REMCTL_LDFLAGS="$REMCTL_LDFLAGS $GSSAPI_LDFLAGS"
+ REMCTL_LIBS="-lremctl $GSSAPI_LIBS"
+fi
+ rra_remctl_save_CPPFLAGS="$CPPFLAGS"
+ rra_remctl_save_LDFLAGS="$LDFLAGS"
+ rra_remctl_save_LIBS="$LIBS"
+ CPPFLAGS="$REMCTL_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$REMCTL_LDFLAGS $LDFLAGS"
+ LIBS="$REMCTL_LIBS $LIBS"
+ ac_fn_c_check_func "$LINENO" "remctl_open" "ac_cv_func_remctl_open"
+if test "x$ac_cv_func_remctl_open" = x""yes; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "unable to link with remctl library
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ CPPFLAGS="$rra_remctl_save_CPPFLAGS"
+ LDFLAGS="$rra_remctl_save_LDFLAGS"
+ LIBS="$rra_remctl_save_LIBS"
+rra_krb5_root=
+ rra_krb5_libdir=
+ rra_krb5_includedir=
+ KRB5_CPPFLAGS=
+ KRB5_LDFLAGS=
+ KRB5_LIBS=
+
+
+
+
+
+# Check whether --with-krb5 was given.
+if test "${with_krb5+set}" = set; then :
+ withval=$with_krb5; if test x"$withval" != xyes && test x"$withval" != xno; then :
+ rra_krb5_root="$withval"
+fi
+fi
+
+
+# Check whether --with-krb5-include was given.
+if test "${with_krb5_include+set}" = set; then :
+ withval=$with_krb5_include; if test x"$withval" != xyes && test x"$withval" != xno; then :
+ rra_krb5_includedir="$withval"
+fi
+fi
+
+
+# Check whether --with-krb5-lib was given.
+if test "${with_krb5_lib+set}" = set; then :
+ withval=$with_krb5_lib; if test x"$withval" != xyes && test x"$withval" != xno; then :
+ rra_krb5_libdir="$withval"
+fi
+fi
+
+
+ if test x"$rra_reduced_depends" = xtrue; then :
+ if test x"$rra_krb5_libdir" != x; then :
+ KRB5_LDFLAGS="-L$rra_krb5_libdir"
+else
+ if test x"$rra_krb5_root" != x; then :
+
+ if test -d "$rra_krb5_root/$rra_lib_arch_name"; then :
+ if test x"" = x; then :
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/${rra_lib_arch_name}"
+else
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/${rra_lib_arch_name}/"
+fi
+else
+ if test x"" = x; then :
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/lib"
+else
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/lib/"
+fi
+fi
+ KRB5_LDFLAGS=`echo "$KRB5_LDFLAGS" | sed -e 's/^ *//'`
+fi
+fi
+ if test x"$rra_krb5_includedir" != x; then :
+ KRB5_CPPFLAGS="-I$rra_krb5_includedir"
+else
+ if test x"$rra_krb5_root" != x; then :
+ if test x"$rra_krb5_root" != x/usr; then :
+ KRB5_CPPFLAGS="-I${rra_krb5_root}/include"
+fi
+fi
+fi
+ rra_krb5_save_CPPFLAGS="$CPPFLAGS"
+ rra_krb5_save_LDFLAGS="$LDFLAGS"
+ rra_krb5_save_LIBS="$LIBS"
+ CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$KRB5_LDFLAGS $LDFLAGS"
+ LIBS="$KRB5_LIBS $LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_init_context in -lkrb5" >&5
+$as_echo_n "checking for krb5_init_context in -lkrb5... " >&6; }
+if test "${ac_cv_lib_krb5_krb5_init_context+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5 $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 krb5_init_context ();
+int
+main ()
+{
+return krb5_init_context ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5_krb5_init_context=yes
+else
+ ac_cv_lib_krb5_krb5_init_context=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_krb5_krb5_init_context" >&5
+$as_echo "$ac_cv_lib_krb5_krb5_init_context" >&6; }
+if test "x$ac_cv_lib_krb5_krb5_init_context" = x""yes; then :
+ KRB5_LIBS="-lkrb5"
+else
+ if test x"true" = xtrue; then :
+ as_fn_error "cannot find usable Kerberos v5 library" "$LINENO" 5
+fi
+fi
+
+ LIBS="$KRB5_LIBS $LIBS"
+ for ac_func in krb5_get_error_message
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_error_message" "ac_cv_func_krb5_get_error_message"
+if test "x$ac_cv_func_krb5_get_error_message" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERROR_MESSAGE 1
+_ACEOF
+ for ac_func in krb5_free_error_message
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_free_error_message" "ac_cv_func_krb5_free_error_message"
+if test "x$ac_cv_func_krb5_free_error_message" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
+_ACEOF
+
+fi
+done
+
+else
+ for ac_func in krb5_get_error_string
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_error_string" "ac_cv_func_krb5_get_error_string"
+if test "x$ac_cv_func_krb5_get_error_string" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERROR_STRING 1
+_ACEOF
+
+else
+ for ac_func in krb5_get_err_txt
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_err_txt" "ac_cv_func_krb5_get_err_txt"
+if test "x$ac_cv_func_krb5_get_err_txt" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERR_TXT 1
+_ACEOF
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_svc_get_msg in -lksvc" >&5
+$as_echo_n "checking for krb5_svc_get_msg in -lksvc... " >&6; }
+if test "${ac_cv_lib_ksvc_krb5_svc_get_msg+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lksvc $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 krb5_svc_get_msg ();
+int
+main ()
+{
+return krb5_svc_get_msg ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ksvc_krb5_svc_get_msg=yes
+else
+ ac_cv_lib_ksvc_krb5_svc_get_msg=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_ksvc_krb5_svc_get_msg" >&5
+$as_echo "$ac_cv_lib_ksvc_krb5_svc_get_msg" >&6; }
+if test "x$ac_cv_lib_ksvc_krb5_svc_get_msg" = x""yes; then :
+ KRB5_LIBS="$KRB5_LIBS -lksvc"
+ $as_echo "#define HAVE_KRB5_SVC_GET_MSG 1" >>confdefs.h
+
+ for ac_header in ibm_svc/krb5_svc.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "ibm_svc/krb5_svc.h" "ac_cv_header_ibm_svc_krb5_svc_h" "$ac_includes_default"
+if test "x$ac_cv_header_ibm_svc_krb5_svc_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_IBM_SVC_KRB5_SVC_H 1
+_ACEOF
+
+fi
+
+done
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for com_err in -lcom_err" >&5
+$as_echo_n "checking for com_err in -lcom_err... " >&6; }
+if test "${ac_cv_lib_com_err_com_err+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcom_err $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 com_err ();
+int
+main ()
+{
+return com_err ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_com_err_com_err=yes
+else
+ ac_cv_lib_com_err_com_err=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_com_err_com_err" >&5
+$as_echo "$ac_cv_lib_com_err_com_err" >&6; }
+if test "x$ac_cv_lib_com_err_com_err" = x""yes; then :
+ KRB5_LIBS="$KRB5_LIBS -lcom_err"
+else
+ as_fn_error "cannot find usable com_err library" "$LINENO" 5
+fi
+
+ for ac_header in et/com_err.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "et/com_err.h" "ac_cv_header_et_com_err_h" "$ac_includes_default"
+if test "x$ac_cv_header_et_com_err_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ET_COM_ERR_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+
+fi
+done
+
+fi
+done
+
+fi
+done
+
+ CPPFLAGS="$rra_krb5_save_CPPFLAGS"
+ LDFLAGS="$rra_krb5_save_LDFLAGS"
+ LIBS="$rra_krb5_save_LIBS"
+else
+
+ if test x"$rra_krb5_root" != x && test -z "$KRB5_CONFIG"; then :
+ if test -x "${rra_krb5_root}/bin/krb5-config"; then :
+ KRB5_CONFIG="${rra_krb5_root}/bin/krb5-config"
+fi
+else
+ # Extract the first word of "krb5-config", so it can be a program name with args.
+set dummy krb5-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_KRB5_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $KRB5_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_KRB5_CONFIG="$KRB5_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_KRB5_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+KRB5_CONFIG=$ac_cv_path_KRB5_CONFIG
+if test -n "$KRB5_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KRB5_CONFIG" >&5
+$as_echo "$KRB5_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+ if test x"$KRB5_CONFIG" != x && test -x "$KRB5_CONFIG"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5 support in krb5-config" >&5
+$as_echo_n "checking for krb5 support in krb5-config... " >&6; }
+if test "${rra_cv_lib_krb5_config+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if "$KRB5_CONFIG" 2>&1 | grep krb5 >/dev/null 2>&1; then :
+ rra_cv_lib_krb5_config=yes
+else
+ rra_cv_lib_krb5_config=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rra_cv_lib_krb5_config" >&5
+$as_echo "$rra_cv_lib_krb5_config" >&6; }
+ if test x"$rra_cv_lib_krb5_config" = xyes; then :
+ KRB5_CPPFLAGS=`"$KRB5_CONFIG" --cflags krb5 2>/dev/null`
+ KRB5_LIBS=`"$KRB5_CONFIG" --libs krb5 2>/dev/null`
+else
+ KRB5_CPPFLAGS=`"$KRB5_CONFIG" --cflags 2>/dev/null`
+ KRB5_LIBS=`"$KRB5_CONFIG" --libs 2>/dev/null`
+fi
+ KRB5_CPPFLAGS=`echo "$KRB5_CPPFLAGS" | sed 's%-I/usr/include ?%%'`
+ rra_krb5_save_CPPFLAGS="$CPPFLAGS"
+ rra_krb5_save_LDFLAGS="$LDFLAGS"
+ rra_krb5_save_LIBS="$LIBS"
+ CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$KRB5_LDFLAGS $LDFLAGS"
+ LIBS="$KRB5_LIBS $LIBS"
+ ac_fn_c_check_func "$LINENO" "krb5_init_context" "ac_cv_func_krb5_init_context"
+if test "x$ac_cv_func_krb5_init_context" = x""yes; then :
+ CPPFLAGS="$rra_krb5_save_CPPFLAGS"
+ LDFLAGS="$rra_krb5_save_LDFLAGS"
+ LIBS="$rra_krb5_save_LIBS"
+else
+ CPPFLAGS="$rra_krb5_save_CPPFLAGS"
+ LDFLAGS="$rra_krb5_save_LDFLAGS"
+ LIBS="$rra_krb5_save_LIBS"
+ KRB5_CPPFLAGS=
+ KRB5_LIBS=
+ if test x"$rra_krb5_libdir" != x; then :
+ KRB5_LDFLAGS="-L$rra_krb5_libdir"
+else
+ if test x"$rra_krb5_root" != x; then :
+
+ if test -d "$rra_krb5_root/$rra_lib_arch_name"; then :
+ if test x"" = x; then :
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/${rra_lib_arch_name}"
+else
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/${rra_lib_arch_name}/"
+fi
+else
+ if test x"" = x; then :
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/lib"
+else
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/lib/"
+fi
+fi
+ KRB5_LDFLAGS=`echo "$KRB5_LDFLAGS" | sed -e 's/^ *//'`
+fi
+fi
+ if test x"$rra_krb5_includedir" != x; then :
+ KRB5_CPPFLAGS="-I$rra_krb5_includedir"
+else
+ if test x"$rra_krb5_root" != x; then :
+ if test x"$rra_krb5_root" != x/usr; then :
+ KRB5_CPPFLAGS="-I${rra_krb5_root}/include"
+fi
+fi
+fi
+ rra_krb5_save_CPPFLAGS="$CPPFLAGS"
+ rra_krb5_save_LDFLAGS="$LDFLAGS"
+ rra_krb5_save_LIBS="$LIBS"
+ CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$KRB5_LDFLAGS $LDFLAGS"
+ LIBS="$KRB5_LIBS $LIBS"
+ rra_krb5_extra=
+ LIBS=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_search" >&5
+$as_echo_n "checking for library containing res_search... " >&6; }
+if test "${ac_cv_search_res_search+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 res_search ();
+int
+main ()
+{
+return res_search ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_res_search=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_res_search+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_res_search+set}" = set; then :
+
+else
+ ac_cv_search_res_search=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_res_search" >&5
+$as_echo "$ac_cv_search_res_search" >&6; }
+ac_res=$ac_cv_search_res_search
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing __res_search" >&5
+$as_echo_n "checking for library containing __res_search... " >&6; }
+if test "${ac_cv_search___res_search+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 __res_search ();
+int
+main ()
+{
+return __res_search ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search___res_search=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search___res_search+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search___res_search+set}" = set; then :
+
+else
+ ac_cv_search___res_search=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search___res_search" >&5
+$as_echo "$ac_cv_search___res_search" >&6; }
+ac_res=$ac_cv_search___res_search
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5
+$as_echo_n "checking for library containing gethostbyname... " >&6; }
+if test "${ac_cv_search_gethostbyname+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' nsl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_gethostbyname=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_gethostbyname+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_gethostbyname+set}" = set; then :
+
+else
+ ac_cv_search_gethostbyname=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5
+$as_echo "$ac_cv_search_gethostbyname" >&6; }
+ac_res=$ac_cv_search_gethostbyname
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5
+$as_echo_n "checking for library containing socket... " >&6; }
+if test "${ac_cv_search_socket+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_socket=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_socket+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_socket+set}" = set; then :
+
+else
+ ac_cv_search_socket=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5
+$as_echo "$ac_cv_search_socket" >&6; }
+ac_res=$ac_cv_search_socket
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lnsl" >&5
+$as_echo_n "checking for socket in -lnsl... " >&6; }
+if test "${ac_cv_lib_nsl_socket+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl -lsocket $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 socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_socket=yes
+else
+ ac_cv_lib_nsl_socket=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_nsl_socket" >&5
+$as_echo "$ac_cv_lib_nsl_socket" >&6; }
+if test "x$ac_cv_lib_nsl_socket" = x""yes; then :
+ LIBS="-lnsl -lsocket $LIBS"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5
+$as_echo_n "checking for library containing crypt... " >&6; }
+if test "${ac_cv_search_crypt+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 crypt ();
+int
+main ()
+{
+return crypt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' crypt; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_crypt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_crypt+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_crypt+set}" = set; then :
+
+else
+ ac_cv_search_crypt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5
+$as_echo "$ac_cv_search_crypt" >&6; }
+ac_res=$ac_cv_search_crypt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ rra_krb5_extra="$LIBS"
+ LIBS="$rra_krb5_save_LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_init_context in -lkrb5" >&5
+$as_echo_n "checking for krb5_init_context in -lkrb5... " >&6; }
+if test "${ac_cv_lib_krb5_krb5_init_context+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5 -lasn1 -lroken -lcrypto -lcom_err $rra_krb5_extra $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 krb5_init_context ();
+int
+main ()
+{
+return krb5_init_context ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5_krb5_init_context=yes
+else
+ ac_cv_lib_krb5_krb5_init_context=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_krb5_krb5_init_context" >&5
+$as_echo "$ac_cv_lib_krb5_krb5_init_context" >&6; }
+if test "x$ac_cv_lib_krb5_krb5_init_context" = x""yes; then :
+ KRB5_LIBS="-lkrb5 -lasn1 -lroken -lcrypto -lcom_err $rra_krb5_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_getspecific in -lkrb5support" >&5
+$as_echo_n "checking for krb5int_getspecific in -lkrb5support... " >&6; }
+if test "${ac_cv_lib_krb5support_krb5int_getspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $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 krb5int_getspecific ();
+int
+main ()
+{
+return krb5int_getspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5support_krb5int_getspecific=yes
+else
+ ac_cv_lib_krb5support_krb5int_getspecific=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_krb5support_krb5int_getspecific" >&5
+$as_echo "$ac_cv_lib_krb5support_krb5int_getspecific" >&6; }
+if test "x$ac_cv_lib_krb5support_krb5int_getspecific" = x""yes; then :
+ rra_krb5_extra="-lkrb5support $rra_krb5_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setspecific in -lpthreads" >&5
+$as_echo_n "checking for pthread_setspecific in -lpthreads... " >&6; }
+if test "${ac_cv_lib_pthreads_pthread_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads $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 pthread_setspecific ();
+int
+main ()
+{
+return pthread_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthreads_pthread_setspecific=yes
+else
+ ac_cv_lib_pthreads_pthread_setspecific=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_pthreads_pthread_setspecific" >&5
+$as_echo "$ac_cv_lib_pthreads_pthread_setspecific" >&6; }
+if test "x$ac_cv_lib_pthreads_pthread_setspecific" = x""yes; then :
+ rra_krb5_pthread="-lpthreads"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setspecific in -lpthread" >&5
+$as_echo_n "checking for pthread_setspecific in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $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 pthread_setspecific ();
+int
+main ()
+{
+return pthread_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_pthread_setspecific=yes
+else
+ ac_cv_lib_pthread_pthread_setspecific=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_pthread_pthread_setspecific" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_setspecific" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_setspecific" = x""yes; then :
+ rra_krb5_pthread="-lpthread"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_setspecific in -lkrb5support" >&5
+$as_echo_n "checking for krb5int_setspecific in -lkrb5support... " >&6; }
+if test "${ac_cv_lib_krb5support_krb5int_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $rra_krb5_pthread $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 krb5int_setspecific ();
+int
+main ()
+{
+return krb5int_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5support_krb5int_setspecific=yes
+else
+ ac_cv_lib_krb5support_krb5int_setspecific=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_krb5support_krb5int_setspecific" >&5
+$as_echo "$ac_cv_lib_krb5support_krb5int_setspecific" >&6; }
+if test "x$ac_cv_lib_krb5support_krb5int_setspecific" = x""yes; then :
+ rra_krb5_extra="-lkrb5support $rra_krb5_extra $rra_krb5_pthread"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_message in -lcom_err" >&5
+$as_echo_n "checking for error_message in -lcom_err... " >&6; }
+if test "${ac_cv_lib_com_err_error_message+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcom_err $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 error_message ();
+int
+main ()
+{
+return error_message ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_com_err_error_message=yes
+else
+ ac_cv_lib_com_err_error_message=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_com_err_error_message" >&5
+$as_echo "$ac_cv_lib_com_err_error_message" >&6; }
+if test "x$ac_cv_lib_com_err_error_message" = x""yes; then :
+ rra_krb5_extra="-lcom_err $rra_krb5_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_svc_get_msg in -lksvc" >&5
+$as_echo_n "checking for krb5_svc_get_msg in -lksvc... " >&6; }
+if test "${ac_cv_lib_ksvc_krb5_svc_get_msg+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lksvc $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 krb5_svc_get_msg ();
+int
+main ()
+{
+return krb5_svc_get_msg ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ksvc_krb5_svc_get_msg=yes
+else
+ ac_cv_lib_ksvc_krb5_svc_get_msg=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_ksvc_krb5_svc_get_msg" >&5
+$as_echo "$ac_cv_lib_ksvc_krb5_svc_get_msg" >&6; }
+if test "x$ac_cv_lib_ksvc_krb5_svc_get_msg" = x""yes; then :
+ rra_krb5_extra="-lksvc $rra_krb5_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_hash_md5 in -lk5crypto" >&5
+$as_echo_n "checking for krb5int_hash_md5 in -lk5crypto... " >&6; }
+if test "${ac_cv_lib_k5crypto_krb5int_hash_md5+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lk5crypto $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 krb5int_hash_md5 ();
+int
+main ()
+{
+return krb5int_hash_md5 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_k5crypto_krb5int_hash_md5=yes
+else
+ ac_cv_lib_k5crypto_krb5int_hash_md5=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_k5crypto_krb5int_hash_md5" >&5
+$as_echo "$ac_cv_lib_k5crypto_krb5int_hash_md5" >&6; }
+if test "x$ac_cv_lib_k5crypto_krb5int_hash_md5" = x""yes; then :
+ rra_krb5_extra="-lk5crypto $rra_krb5_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for profile_get_values in -lk5profile" >&5
+$as_echo_n "checking for profile_get_values in -lk5profile... " >&6; }
+if test "${ac_cv_lib_k5profile_profile_get_values+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lk5profile $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 profile_get_values ();
+int
+main ()
+{
+return profile_get_values ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_k5profile_profile_get_values=yes
+else
+ ac_cv_lib_k5profile_profile_get_values=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_k5profile_profile_get_values" >&5
+$as_echo "$ac_cv_lib_k5profile_profile_get_values" >&6; }
+if test "x$ac_cv_lib_k5profile_profile_get_values" = x""yes; then :
+ rra_krb5_extra="-lk5profile $rra_krb5_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_cc_default in -lkrb5" >&5
+$as_echo_n "checking for krb5_cc_default in -lkrb5... " >&6; }
+if test "${ac_cv_lib_krb5_krb5_cc_default+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5 $rra_krb5_extra $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 krb5_cc_default ();
+int
+main ()
+{
+return krb5_cc_default ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5_krb5_cc_default=yes
+else
+ ac_cv_lib_krb5_krb5_cc_default=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_krb5_krb5_cc_default" >&5
+$as_echo "$ac_cv_lib_krb5_krb5_cc_default" >&6; }
+if test "x$ac_cv_lib_krb5_krb5_cc_default" = x""yes; then :
+ KRB5_LIBS="-lkrb5 $rra_krb5_extra"
+else
+ if test x"true" = xtrue; then :
+ as_fn_error "cannot find usable Kerberos v5 library" "$LINENO" 5
+fi
+fi
+
+fi
+
+ LIBS="$KRB5_LIBS $LIBS"
+ for ac_func in krb5_get_error_message
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_error_message" "ac_cv_func_krb5_get_error_message"
+if test "x$ac_cv_func_krb5_get_error_message" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERROR_MESSAGE 1
+_ACEOF
+ for ac_func in krb5_free_error_message
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_free_error_message" "ac_cv_func_krb5_free_error_message"
+if test "x$ac_cv_func_krb5_free_error_message" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
+_ACEOF
+
+fi
+done
+
+else
+ for ac_func in krb5_get_error_string
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_error_string" "ac_cv_func_krb5_get_error_string"
+if test "x$ac_cv_func_krb5_get_error_string" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERROR_STRING 1
+_ACEOF
+
+else
+ for ac_func in krb5_get_err_txt
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_err_txt" "ac_cv_func_krb5_get_err_txt"
+if test "x$ac_cv_func_krb5_get_err_txt" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERR_TXT 1
+_ACEOF
+
+else
+ for ac_func in krb5_svc_get_msg
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_svc_get_msg" "ac_cv_func_krb5_svc_get_msg"
+if test "x$ac_cv_func_krb5_svc_get_msg" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_SVC_GET_MSG 1
+_ACEOF
+ for ac_header in ibm_svc/krb5_svc.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "ibm_svc/krb5_svc.h" "ac_cv_header_ibm_svc_krb5_svc_h" "$ac_includes_default"
+if test "x$ac_cv_header_ibm_svc_krb5_svc_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_IBM_SVC_KRB5_SVC_H 1
+_ACEOF
+
+fi
+
+done
+
+else
+ for ac_header in et/com_err.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "et/com_err.h" "ac_cv_header_et_com_err_h" "$ac_includes_default"
+if test "x$ac_cv_header_et_com_err_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ET_COM_ERR_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+done
+
+fi
+done
+
+fi
+done
+
+fi
+done
+
+ CPPFLAGS="$rra_krb5_save_CPPFLAGS"
+ LDFLAGS="$rra_krb5_save_LDFLAGS"
+ LIBS="$rra_krb5_save_LIBS"
+fi
+
+ rra_krb5_save_CPPFLAGS="$CPPFLAGS"
+ rra_krb5_save_LDFLAGS="$LDFLAGS"
+ rra_krb5_save_LIBS="$LIBS"
+ CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$KRB5_LDFLAGS $LDFLAGS"
+ LIBS="$KRB5_LIBS $LIBS"
+ for ac_func in krb5_get_error_message
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_error_message" "ac_cv_func_krb5_get_error_message"
+if test "x$ac_cv_func_krb5_get_error_message" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERROR_MESSAGE 1
+_ACEOF
+ for ac_func in krb5_free_error_message
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_free_error_message" "ac_cv_func_krb5_free_error_message"
+if test "x$ac_cv_func_krb5_free_error_message" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
+_ACEOF
+
+fi
+done
+
+else
+ for ac_func in krb5_get_error_string
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_error_string" "ac_cv_func_krb5_get_error_string"
+if test "x$ac_cv_func_krb5_get_error_string" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERROR_STRING 1
+_ACEOF
+
+else
+ for ac_func in krb5_get_err_txt
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_err_txt" "ac_cv_func_krb5_get_err_txt"
+if test "x$ac_cv_func_krb5_get_err_txt" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERR_TXT 1
+_ACEOF
+
+else
+ for ac_func in krb5_svc_get_msg
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_svc_get_msg" "ac_cv_func_krb5_svc_get_msg"
+if test "x$ac_cv_func_krb5_svc_get_msg" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_SVC_GET_MSG 1
+_ACEOF
+ for ac_header in ibm_svc/krb5_svc.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "ibm_svc/krb5_svc.h" "ac_cv_header_ibm_svc_krb5_svc_h" "$ac_includes_default"
+if test "x$ac_cv_header_ibm_svc_krb5_svc_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_IBM_SVC_KRB5_SVC_H 1
+_ACEOF
+
+fi
+
+done
+
+else
+ for ac_header in et/com_err.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "et/com_err.h" "ac_cv_header_et_com_err_h" "$ac_includes_default"
+if test "x$ac_cv_header_et_com_err_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ET_COM_ERR_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+done
+
+fi
+done
+
+fi
+done
+
+fi
+done
+
+ CPPFLAGS="$rra_krb5_save_CPPFLAGS"
+ LDFLAGS="$rra_krb5_save_LDFLAGS"
+ LIBS="$rra_krb5_save_LIBS"
+else
+ if test x"$rra_krb5_libdir" != x; then :
+ KRB5_LDFLAGS="-L$rra_krb5_libdir"
+else
+ if test x"$rra_krb5_root" != x; then :
+
+ if test -d "$rra_krb5_root/$rra_lib_arch_name"; then :
+ if test x"" = x; then :
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/${rra_lib_arch_name}"
+else
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/${rra_lib_arch_name}/"
+fi
+else
+ if test x"" = x; then :
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/lib"
+else
+ KRB5_LDFLAGS="$KRB5_LDFLAGS -L$rra_krb5_root/lib/"
+fi
+fi
+ KRB5_LDFLAGS=`echo "$KRB5_LDFLAGS" | sed -e 's/^ *//'`
+fi
+fi
+ if test x"$rra_krb5_includedir" != x; then :
+ KRB5_CPPFLAGS="-I$rra_krb5_includedir"
+else
+ if test x"$rra_krb5_root" != x; then :
+ if test x"$rra_krb5_root" != x/usr; then :
+ KRB5_CPPFLAGS="-I${rra_krb5_root}/include"
+fi
+fi
+fi
+ rra_krb5_save_CPPFLAGS="$CPPFLAGS"
+ rra_krb5_save_LDFLAGS="$LDFLAGS"
+ rra_krb5_save_LIBS="$LIBS"
+ CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$KRB5_LDFLAGS $LDFLAGS"
+ LIBS="$KRB5_LIBS $LIBS"
+ rra_krb5_extra=
+ LIBS=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_search" >&5
+$as_echo_n "checking for library containing res_search... " >&6; }
+if test "${ac_cv_search_res_search+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 res_search ();
+int
+main ()
+{
+return res_search ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_res_search=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_res_search+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_res_search+set}" = set; then :
+
+else
+ ac_cv_search_res_search=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_res_search" >&5
+$as_echo "$ac_cv_search_res_search" >&6; }
+ac_res=$ac_cv_search_res_search
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing __res_search" >&5
+$as_echo_n "checking for library containing __res_search... " >&6; }
+if test "${ac_cv_search___res_search+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 __res_search ();
+int
+main ()
+{
+return __res_search ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' resolv; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search___res_search=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search___res_search+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search___res_search+set}" = set; then :
+
+else
+ ac_cv_search___res_search=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search___res_search" >&5
+$as_echo "$ac_cv_search___res_search" >&6; }
+ac_res=$ac_cv_search___res_search
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5
+$as_echo_n "checking for library containing gethostbyname... " >&6; }
+if test "${ac_cv_search_gethostbyname+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 gethostbyname ();
+int
+main ()
+{
+return gethostbyname ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' nsl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_gethostbyname=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_gethostbyname+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_gethostbyname+set}" = set; then :
+
+else
+ ac_cv_search_gethostbyname=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5
+$as_echo "$ac_cv_search_gethostbyname" >&6; }
+ac_res=$ac_cv_search_gethostbyname
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5
+$as_echo_n "checking for library containing socket... " >&6; }
+if test "${ac_cv_search_socket+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_socket=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_socket+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_socket+set}" = set; then :
+
+else
+ ac_cv_search_socket=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5
+$as_echo "$ac_cv_search_socket" >&6; }
+ac_res=$ac_cv_search_socket
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lnsl" >&5
+$as_echo_n "checking for socket in -lnsl... " >&6; }
+if test "${ac_cv_lib_nsl_socket+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl -lsocket $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 socket ();
+int
+main ()
+{
+return socket ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_socket=yes
+else
+ ac_cv_lib_nsl_socket=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_nsl_socket" >&5
+$as_echo "$ac_cv_lib_nsl_socket" >&6; }
+if test "x$ac_cv_lib_nsl_socket" = x""yes; then :
+ LIBS="-lnsl -lsocket $LIBS"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5
+$as_echo_n "checking for library containing crypt... " >&6; }
+if test "${ac_cv_search_crypt+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$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 crypt ();
+int
+main ()
+{
+return crypt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' crypt; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_crypt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_crypt+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_crypt+set}" = set; then :
+
+else
+ ac_cv_search_crypt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5
+$as_echo "$ac_cv_search_crypt" >&6; }
+ac_res=$ac_cv_search_crypt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ rra_krb5_extra="$LIBS"
+ LIBS="$rra_krb5_save_LIBS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_init_context in -lkrb5" >&5
+$as_echo_n "checking for krb5_init_context in -lkrb5... " >&6; }
+if test "${ac_cv_lib_krb5_krb5_init_context+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5 -lasn1 -lroken -lcrypto -lcom_err $rra_krb5_extra $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 krb5_init_context ();
+int
+main ()
+{
+return krb5_init_context ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5_krb5_init_context=yes
+else
+ ac_cv_lib_krb5_krb5_init_context=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_krb5_krb5_init_context" >&5
+$as_echo "$ac_cv_lib_krb5_krb5_init_context" >&6; }
+if test "x$ac_cv_lib_krb5_krb5_init_context" = x""yes; then :
+ KRB5_LIBS="-lkrb5 -lasn1 -lroken -lcrypto -lcom_err $rra_krb5_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_getspecific in -lkrb5support" >&5
+$as_echo_n "checking for krb5int_getspecific in -lkrb5support... " >&6; }
+if test "${ac_cv_lib_krb5support_krb5int_getspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $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 krb5int_getspecific ();
+int
+main ()
+{
+return krb5int_getspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5support_krb5int_getspecific=yes
+else
+ ac_cv_lib_krb5support_krb5int_getspecific=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_krb5support_krb5int_getspecific" >&5
+$as_echo "$ac_cv_lib_krb5support_krb5int_getspecific" >&6; }
+if test "x$ac_cv_lib_krb5support_krb5int_getspecific" = x""yes; then :
+ rra_krb5_extra="-lkrb5support $rra_krb5_extra"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setspecific in -lpthreads" >&5
+$as_echo_n "checking for pthread_setspecific in -lpthreads... " >&6; }
+if test "${ac_cv_lib_pthreads_pthread_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreads $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 pthread_setspecific ();
+int
+main ()
+{
+return pthread_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthreads_pthread_setspecific=yes
+else
+ ac_cv_lib_pthreads_pthread_setspecific=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_pthreads_pthread_setspecific" >&5
+$as_echo "$ac_cv_lib_pthreads_pthread_setspecific" >&6; }
+if test "x$ac_cv_lib_pthreads_pthread_setspecific" = x""yes; then :
+ rra_krb5_pthread="-lpthreads"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setspecific in -lpthread" >&5
+$as_echo_n "checking for pthread_setspecific in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $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 pthread_setspecific ();
+int
+main ()
+{
+return pthread_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_pthread_setspecific=yes
+else
+ ac_cv_lib_pthread_pthread_setspecific=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_pthread_pthread_setspecific" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_setspecific" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_setspecific" = x""yes; then :
+ rra_krb5_pthread="-lpthread"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_setspecific in -lkrb5support" >&5
+$as_echo_n "checking for krb5int_setspecific in -lkrb5support... " >&6; }
+if test "${ac_cv_lib_krb5support_krb5int_setspecific+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support $rra_krb5_pthread $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 krb5int_setspecific ();
+int
+main ()
+{
+return krb5int_setspecific ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5support_krb5int_setspecific=yes
+else
+ ac_cv_lib_krb5support_krb5int_setspecific=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_krb5support_krb5int_setspecific" >&5
+$as_echo "$ac_cv_lib_krb5support_krb5int_setspecific" >&6; }
+if test "x$ac_cv_lib_krb5support_krb5int_setspecific" = x""yes; then :
+ rra_krb5_extra="-lkrb5support $rra_krb5_extra $rra_krb5_pthread"
+fi
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_message in -lcom_err" >&5
+$as_echo_n "checking for error_message in -lcom_err... " >&6; }
+if test "${ac_cv_lib_com_err_error_message+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcom_err $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 error_message ();
+int
+main ()
+{
+return error_message ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_com_err_error_message=yes
+else
+ ac_cv_lib_com_err_error_message=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_com_err_error_message" >&5
+$as_echo "$ac_cv_lib_com_err_error_message" >&6; }
+if test "x$ac_cv_lib_com_err_error_message" = x""yes; then :
+ rra_krb5_extra="-lcom_err $rra_krb5_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_svc_get_msg in -lksvc" >&5
+$as_echo_n "checking for krb5_svc_get_msg in -lksvc... " >&6; }
+if test "${ac_cv_lib_ksvc_krb5_svc_get_msg+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lksvc $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 krb5_svc_get_msg ();
+int
+main ()
+{
+return krb5_svc_get_msg ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_ksvc_krb5_svc_get_msg=yes
+else
+ ac_cv_lib_ksvc_krb5_svc_get_msg=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_ksvc_krb5_svc_get_msg" >&5
+$as_echo "$ac_cv_lib_ksvc_krb5_svc_get_msg" >&6; }
+if test "x$ac_cv_lib_ksvc_krb5_svc_get_msg" = x""yes; then :
+ rra_krb5_extra="-lksvc $rra_krb5_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5int_hash_md5 in -lk5crypto" >&5
+$as_echo_n "checking for krb5int_hash_md5 in -lk5crypto... " >&6; }
+if test "${ac_cv_lib_k5crypto_krb5int_hash_md5+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lk5crypto $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 krb5int_hash_md5 ();
+int
+main ()
+{
+return krb5int_hash_md5 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_k5crypto_krb5int_hash_md5=yes
+else
+ ac_cv_lib_k5crypto_krb5int_hash_md5=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_k5crypto_krb5int_hash_md5" >&5
+$as_echo "$ac_cv_lib_k5crypto_krb5int_hash_md5" >&6; }
+if test "x$ac_cv_lib_k5crypto_krb5int_hash_md5" = x""yes; then :
+ rra_krb5_extra="-lk5crypto $rra_krb5_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for profile_get_values in -lk5profile" >&5
+$as_echo_n "checking for profile_get_values in -lk5profile... " >&6; }
+if test "${ac_cv_lib_k5profile_profile_get_values+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lk5profile $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 profile_get_values ();
+int
+main ()
+{
+return profile_get_values ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_k5profile_profile_get_values=yes
+else
+ ac_cv_lib_k5profile_profile_get_values=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_k5profile_profile_get_values" >&5
+$as_echo "$ac_cv_lib_k5profile_profile_get_values" >&6; }
+if test "x$ac_cv_lib_k5profile_profile_get_values" = x""yes; then :
+ rra_krb5_extra="-lk5profile $rra_krb5_extra"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for krb5_cc_default in -lkrb5" >&5
+$as_echo_n "checking for krb5_cc_default in -lkrb5... " >&6; }
+if test "${ac_cv_lib_krb5_krb5_cc_default+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5 $rra_krb5_extra $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 krb5_cc_default ();
+int
+main ()
+{
+return krb5_cc_default ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_krb5_krb5_cc_default=yes
+else
+ ac_cv_lib_krb5_krb5_cc_default=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_krb5_krb5_cc_default" >&5
+$as_echo "$ac_cv_lib_krb5_krb5_cc_default" >&6; }
+if test "x$ac_cv_lib_krb5_krb5_cc_default" = x""yes; then :
+ KRB5_LIBS="-lkrb5 $rra_krb5_extra"
+else
+ if test x"true" = xtrue; then :
+ as_fn_error "cannot find usable Kerberos v5 library" "$LINENO" 5
+fi
+fi
+
+fi
+
+ LIBS="$KRB5_LIBS $LIBS"
+ for ac_func in krb5_get_error_message
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_error_message" "ac_cv_func_krb5_get_error_message"
+if test "x$ac_cv_func_krb5_get_error_message" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERROR_MESSAGE 1
+_ACEOF
+ for ac_func in krb5_free_error_message
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_free_error_message" "ac_cv_func_krb5_free_error_message"
+if test "x$ac_cv_func_krb5_free_error_message" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
+_ACEOF
+
+fi
+done
+
+else
+ for ac_func in krb5_get_error_string
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_error_string" "ac_cv_func_krb5_get_error_string"
+if test "x$ac_cv_func_krb5_get_error_string" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERROR_STRING 1
+_ACEOF
+
+else
+ for ac_func in krb5_get_err_txt
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_get_err_txt" "ac_cv_func_krb5_get_err_txt"
+if test "x$ac_cv_func_krb5_get_err_txt" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_GET_ERR_TXT 1
+_ACEOF
+
+else
+ for ac_func in krb5_svc_get_msg
+do :
+ ac_fn_c_check_func "$LINENO" "krb5_svc_get_msg" "ac_cv_func_krb5_svc_get_msg"
+if test "x$ac_cv_func_krb5_svc_get_msg" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_SVC_GET_MSG 1
+_ACEOF
+ for ac_header in ibm_svc/krb5_svc.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "ibm_svc/krb5_svc.h" "ac_cv_header_ibm_svc_krb5_svc_h" "$ac_includes_default"
+if test "x$ac_cv_header_ibm_svc_krb5_svc_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_IBM_SVC_KRB5_SVC_H 1
+_ACEOF
+
+fi
+
+done
+
+else
+ for ac_header in et/com_err.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "et/com_err.h" "ac_cv_header_et_com_err_h" "$ac_includes_default"
+if test "x$ac_cv_header_et_com_err_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_ET_COM_ERR_H 1
+_ACEOF
+
+fi
+
+done
+
+fi
+done
+
+fi
+done
+
+fi
+done
+
+fi
+done
+
+ CPPFLAGS="$rra_krb5_save_CPPFLAGS"
+ LDFLAGS="$rra_krb5_save_LDFLAGS"
+ LIBS="$rra_krb5_save_LIBS"
+fi
+fi
+ rra_krb5_uses_com_err=false
+ case "$LIBS" in
+ *-lcom_err*)
+ rra_krb5_uses_com_err=true
+ ;;
+ esac
+ if test x"$rra_krb5_uses_com_err" = xtrue; then
+ KRB5_USES_COM_ERR_TRUE=
+ KRB5_USES_COM_ERR_FALSE='#'
+else
+ KRB5_USES_COM_ERR_TRUE='#'
+ KRB5_USES_COM_ERR_FALSE=
+fi
+
+rra_krb5_save_CPPFLAGS="$CPPFLAGS"
+ rra_krb5_save_LDFLAGS="$LDFLAGS"
+ rra_krb5_save_LIBS="$LIBS"
+ CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$KRB5_LDFLAGS $LDFLAGS"
+ LIBS="$KRB5_LIBS $LIBS"
+for ac_func in krb5_get_init_creds_opt_alloc \
+ krb5_get_init_creds_opt_set_default_flags \
+ krb5_kt_free_entry \
+ krb5_principal_get_realm
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ac_fn_c_check_member "$LINENO" "krb5_keytab_entry" "keyblock" "ac_cv_member_krb5_keytab_entry_keyblock" "#include <krb5.h>
+"
+if test "x$ac_cv_member_krb5_keytab_entry_keyblock" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK 1
+_ACEOF
+
+
+fi
+
+CPPFLAGS="$rra_krb5_save_CPPFLAGS"
+ LDFLAGS="$rra_krb5_save_LDFLAGS"
+ LIBS="$rra_krb5_save_LIBS"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if test "${ac_cv_header_stdbool_h+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdbool.h>
+#ifndef bool
+ "error: bool is not defined"
+#endif
+#ifndef false
+ "error: false is not defined"
+#endif
+#if false
+ "error: false is not 0"
+#endif
+#ifndef true
+ "error: true is not defined"
+#endif
+#if true != 1
+ "error: true is not 1"
+#endif
+#ifndef __bool_true_false_are_defined
+ "error: __bool_true_false_are_defined is not defined"
+#endif
+
+ struct s { _Bool s: 1; _Bool t; } s;
+
+ char a[true == 1 ? 1 : -1];
+ char b[false == 0 ? 1 : -1];
+ char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+ char d[(bool) 0.5 == true ? 1 : -1];
+ bool e = &s;
+ char f[(_Bool) 0.0 == false ? 1 : -1];
+ char g[true];
+ char h[sizeof (_Bool)];
+ char i[sizeof s.t];
+ enum { j = false, k = true, l = false * true, m = true * 256 };
+ /* The following fails for
+ HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+ _Bool n[m];
+ char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+ char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+# if defined __xlc__ || defined __GNUC__
+ /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0
+ reported by James Lemley on 2005-10-05; see
+ http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
+ This test is not quite right, since xlc is allowed to
+ reject this program, as the initializer for xlcbug is
+ not one of the forms that C requires support for.
+ However, doing the test right would require a runtime
+ test, and that would make cross-compilation harder.
+ Let us hope that IBM fixes the xlc bug, and also adds
+ support for this kind of constant expression. In the
+ meantime, this test will reject xlc, which is OK, since
+ our stdbool.h substitute should suffice. We also test
+ this with GCC, where it should work, to detect more
+ quickly whether someone messes up the test in the
+ future. */
+ char digs[] = "0123456789";
+ int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1);
+# endif
+ /* Catch a bug in an HP-UX C compiler. See
+ http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+ http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+ */
+ _Bool q = true;
+ _Bool *pq = &q;
+
+int
+main ()
+{
+
+ *pq |= q;
+ *pq |= ! q;
+ /* Refer to every declared value, to avoid compiler optimizations. */
+ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+ + !m + !n + !o + !p + !q + !pq);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdbool_h=yes
+else
+ ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
+for ac_header in sys/bitypes.h sys/uio.h syslog.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ac_fn_c_check_decl "$LINENO" "snprintf" "ac_cv_have_decl_snprintf" "$ac_includes_default"
+if test "x$ac_cv_have_decl_snprintf" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SNPRINTF $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "vsnprintf" "ac_cv_have_decl_vsnprintf" "$ac_includes_default"
+if test "x$ac_cv_have_decl_vsnprintf" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VSNPRINTF $ac_have_decl
+_ACEOF
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C99 variadic macros" >&5
+$as_echo_n "checking for C99 variadic macros... " >&6; }
+if test "${rra_cv_c_c99_vamacros+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#define error(...) fprintf(stderr, __VA_ARGS__)
+
+int
+main(void) {
+ error("foo");
+ error("foo %d", 0);
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ rra_cv_c_c99_vamacros=yes
+else
+ rra_cv_c_c99_vamacros=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rra_cv_c_c99_vamacros" >&5
+$as_echo "$rra_cv_c_c99_vamacros" >&6; }
+ if test x"$rra_cv_c_c99_vamacros" = xyes; then :
+
+$as_echo "#define HAVE_C99_VAMACROS 1" >>confdefs.h
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU-style variadic macros" >&5
+$as_echo_n "checking for GNU-style variadic macros... " >&6; }
+if test "${rra_cv_c_gnu_vamacros+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#define error(args...) fprintf(stderr, args)
+
+int
+main(void) {
+ error("foo");
+ error("foo %d", 0);
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ rra_cv_c_gnu_vamacros=yes
+else
+ rra_cv_c_gnu_vamacros=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rra_cv_c_gnu_vamacros" >&5
+$as_echo "$rra_cv_c_gnu_vamacros" >&6; }
+ if test x"$rra_cv_c_gnu_vamacros" = xyes; then :
+
+$as_echo "#define HAVE_GNU_VAMACROS 1" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5
+$as_echo_n "checking for long long int... " >&6; }
+if test "${ac_cv_type_long_long_int+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ /* Test preprocessor. */
+ #if ! (-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ error in preprocessor;
+ #endif
+ #if ! (18446744073709551615ULL <= -1ull)
+ error in preprocessor;
+ #endif
+ /* Test literals. */
+ long long int ll = 9223372036854775807ll;
+ long long int nll = -9223372036854775807LL;
+ unsigned long long int ull = 18446744073709551615ULL;
+ /* Test constant expressions. */
+ typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+ ? 1 : -1)];
+ typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+ ? 1 : -1)];
+ int i = 63;
+int
+main ()
+{
+/* Test availability of runtime routines for shift and division. */
+ long long int llmax = 9223372036854775807ll;
+ unsigned long long int ullmax = 18446744073709551615ull;
+ return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+ | (llmax / ll) | (llmax % ll)
+ | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+ | (ullmax / ull) | (ullmax % ull));
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if test "$cross_compiling" = yes; then :
+ ac_cv_type_long_long_int=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+ #ifndef LLONG_MAX
+ # define HALF \
+ (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+ # define LLONG_MAX (HALF - 1 + HALF)
+ #endif
+int
+main ()
+{
+long long int n = 1;
+ int i;
+ for (i = 0; ; i++)
+ {
+ long long int m = n << i;
+ if (m >> i != n)
+ return 1;
+ if (LLONG_MAX / 2 < m)
+ break;
+ }
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_type_long_long_int=yes
+else
+ ac_cv_type_long_long_int=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+else
+ ac_cv_type_long_long_int=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5
+$as_echo "$ac_cv_type_long_long_int" >&6; }
+ if test $ac_cv_type_long_long_int = yes; then
+
+$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
+
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working snprintf" >&5
+$as_echo_n "checking for working snprintf... " >&6; }
+if test "${rra_cv_func_snprintf_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ rra_cv_func_snprintf_works=no
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+char buf[2];
+
+int
+test(char *format, ...)
+{
+ va_list args;
+ int count;
+
+ va_start(args, format);
+ count = vsnprintf(buf, sizeof buf, format, args);
+ va_end(args);
+ return count;
+}
+
+int
+main()
+{
+ return ((test("%s", "abcd") == 4 && buf[0] == 'a' && buf[1] == '\0'
+ && snprintf(NULL, 0, "%s", "abcd") == 4) ? 0 : 1);
+}
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ rra_cv_func_snprintf_works=yes
+else
+ rra_cv_func_snprintf_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rra_cv_func_snprintf_works" >&5
+$as_echo "$rra_cv_func_snprintf_works" >&6; }
+ if test x"$rra_cv_func_snprintf_works" = xyes; then :
+
+$as_echo "#define HAVE_SNPRINTF 1" >>confdefs.h
+
+else
+ case " $LIBOBJS " in
+ *" snprintf.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS snprintf.$ac_objext"
+ ;;
+esac
+
+fi
+for ac_func in setrlimit
+do :
+ ac_fn_c_check_func "$LINENO" "setrlimit" "ac_cv_func_setrlimit"
+if test "x$ac_cv_func_setrlimit" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SETRLIMIT 1
+_ACEOF
+
+fi
+done
+
+for ac_func in asprintf mkstemp setenv strlcat strlcpy
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+ case " $LIBOBJS " in
+ *" $ac_func.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
+ ;;
+esac
+
+fi
+done
+
+
+
+
+# Check whether --with-wallet-server was given.
+if test "${with_wallet_server+set}" = set; then :
+ withval=$with_wallet_server; if test x"$withval" != xno && test x"$withval" != xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define WALLET_SERVER "$withval"
+_ACEOF
+
+fi
+fi
+
+
+# Check whether --with-wallet-port was given.
+if test "${with_wallet_port+set}" = set; then :
+ withval=$with_wallet_port; if test x"$withval" != xno && test x"$withval" != xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define WALLET_PORT $withval
+_ACEOF
+
+fi
+fi
+
+
+
+# Extract the first word of "remctld", so it can be a program name with args.
+set dummy remctld; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_REMCTLD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $REMCTLD in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_REMCTLD="$REMCTLD" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="$PATH:/usr/sbin:/usr/local/sbin"
+for as_dir in $as_dummy
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_REMCTLD="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+REMCTLD=$ac_cv_path_REMCTLD
+if test -n "$REMCTLD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $REMCTLD" >&5
+$as_echo "$REMCTLD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test x"$REMCTLD" != x; then :
+
+cat >>confdefs.h <<_ACEOF
+#define PATH_REMCTLD "$REMCTLD"
+_ACEOF
+
+fi
+
+ac_config_commands="$ac_config_commands tests/data/.placeholder"
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+ac_config_files="$ac_config_files Makefile perl/Makefile.PL"
+
+ac_config_files="$ac_config_files tests/client/basic-t"
+
+ac_config_files="$ac_config_files tests/client/full-t"
+
+ac_config_files="$ac_config_files tests/client/prompt-t"
+
+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
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${KRB5_USES_COM_ERR_TRUE}" && test -z "${KRB5_USES_COM_ERR_FALSE}"; then
+ as_fn_error "conditional \"KRB5_USES_COM_ERR\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by wallet $as_me 0.10, which was
+generated by GNU Autoconf 2.65. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <rra@stanford.edu>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+wallet config.status 0.10
+configured by $0, generated by GNU Autoconf 2.65,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "tests/data/.placeholder") CONFIG_COMMANDS="$CONFIG_COMMANDS tests/data/.placeholder" ;;
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "perl/Makefile.PL") CONFIG_FILES="$CONFIG_FILES perl/Makefile.PL" ;;
+ "tests/client/basic-t") CONFIG_FILES="$CONFIG_FILES tests/client/basic-t" ;;
+ "tests/client/full-t") CONFIG_FILES="$CONFIG_FILES tests/client/full-t" ;;
+ "tests/client/prompt-t") CONFIG_FILES="$CONFIG_FILES tests/client/prompt-t" ;;
+
+ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "tests/data/.placeholder":C) touch tests/data/.placeholder ;;
+ "tests/client/basic-t":F) chmod +x tests/client/basic-t ;;
+ "tests/client/full-t":F) chmod +x tests/client/full-t ;;
+ "tests/client/prompt-t":F) chmod +x tests/client/prompt-t ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/configure.ac b/configure.ac
index eb772a6..c4dc7eb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,36 +1,46 @@
-dnl Process this file with Autoconf to produce a configure script.
-dnl $Id$
+dnl Autoconf configuration for wallet.
dnl
dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2006, 2007, 2008
+dnl Copyright 2006, 2007, 2008, 2010
dnl Board of Trustees, Leland Stanford Jr. University
dnl
dnl See LICENSE for licensing terms.
-AC_REVISION([$Revision$])
-AC_PREREQ([2.61])
-AC_INIT([wallet], [0.9], [rra@stanford.edu])
+dnl We cannot use -Wall -Werror with AM_INIT_AUTOMAKE since we override
+dnl distuninstallcheck (not supported by Perl).
+AC_PREREQ([2.64])
+AC_INIT([wallet], [0.10], [rra@stanford.edu])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_LIBOBJ_DIR([portable])
-AM_INIT_AUTOMAKE([1.10])
+AC_CONFIG_MACRO_DIR([m4])
+AM_INIT_AUTOMAKE([1.11 check-news silent-rules])
AM_MAINTAINER_MODE
AC_PROG_CC
+AC_USE_SYSTEM_EXTENSIONS
AM_PROG_CC_C_O
AC_PROG_INSTALL
AC_PROG_RANLIB
-AC_AIX
-AC_GNU_SOURCE
+
+RRA_LIB_REMCTL
+RRA_LIB_KRB5
+RRA_LIB_KRB5_SWITCH
+AC_CHECK_FUNCS([krb5_get_init_creds_opt_alloc \
+ krb5_get_init_creds_opt_set_default_flags \
+ krb5_kt_free_entry \
+ krb5_principal_get_realm])
+AC_CHECK_MEMBERS([krb5_keytab_entry.keyblock], , , [#include <krb5.h>])
+RRA_LIB_KRB5_RESTORE
AC_HEADER_STDBOOL
-AC_CHECK_HEADERS([sys/bitypes.h syslog.h])
+AC_CHECK_HEADERS([sys/bitypes.h sys/uio.h syslog.h])
AC_CHECK_DECLS([snprintf, vsnprintf])
RRA_C_C99_VAMACROS
RRA_C_GNU_VAMACROS
-AC_CHECK_TYPES([long long])
+AC_TYPE_LONG_LONG_INT
RRA_FUNC_SNPRINTF
AC_CHECK_FUNCS([setrlimit])
-AC_REPLACE_FUNCS([asprintf strlcat strlcpy])
+AC_REPLACE_FUNCS([asprintf mkstemp setenv strlcat strlcpy])
AC_ARG_WITH([wallet-server],
[AC_HELP_STRING([--with-wallet-server=HOST], [Default wallet server])],
@@ -44,33 +54,18 @@ AC_ARG_WITH([wallet-port],
[AC_DEFINE_UNQUOTED([WALLET_PORT], [$withval],
[Define to the default server port.])])])
-RRA_LIB_REMCTL
-RRA_LIB_KRB5
-RRA_LIB_AFS
-AS_IF([test x"$rra_afs" = xtrue],
- [RRA_LIB_KRB4
- RRA_LIB_AFS_SWITCH
- AC_CHECK_DECLS([ubik_Call], , , [#include <ubik.h>])
- RRA_LIB_AFS_RESTORE])
-AM_CONDITIONAL([AFS], [test x"$rra_afs" = xtrue])
-
AC_ARG_VAR([REMCTLD], [Path to the remctld binary])
AC_PATH_PROG([REMCTLD], [remctld], , [$PATH:/usr/sbin:/usr/local/sbin])
AS_IF([test x"$REMCTLD" != x],
[AC_DEFINE_UNQUOTED([PATH_REMCTLD], ["$REMCTLD"],
[Define to the full path to remctld to run remctl tests.])])
+dnl Create the tests/data directory for builds outside the source directory.
+AC_CONFIG_COMMANDS([tests/data/.placeholder], [touch tests/data/.placeholder])
+
AC_CONFIG_HEADER([config.h])
-AC_CONFIG_FILES([Makefile perl/Makefile.PL tests/data/full.conf])
+AC_CONFIG_FILES([Makefile perl/Makefile.PL])
AC_CONFIG_FILES([tests/client/basic-t], [chmod +x tests/client/basic-t])
AC_CONFIG_FILES([tests/client/full-t], [chmod +x tests/client/full-t])
-AC_CONFIG_FILES([tests/client/pod-t], [chmod +x tests/client/pod-t])
AC_CONFIG_FILES([tests/client/prompt-t], [chmod +x tests/client/prompt-t])
-AC_CONFIG_FILES([tests/data/cmd-wrapper], [chmod +x tests/data/cmd-wrapper])
-AC_CONFIG_FILES([tests/kasetkey/basic-t], [chmod +x tests/kasetkey/basic-t])
-AC_CONFIG_FILES([tests/server/admin-t], [chmod +x tests/server/admin-t])
-AC_CONFIG_FILES([tests/server/backend-t], [chmod +x tests/server/backend-t])
-AC_CONFIG_FILES([tests/server/keytab-t], [chmod +x tests/server/keytab-t])
-AC_CONFIG_FILES([tests/server/pod-t], [chmod +x tests/server/pod-t])
-AC_CONFIG_FILES([tests/util/xmalloc-t], [chmod +x tests/util/xmalloc-t])
AC_OUTPUT
diff --git a/contrib/convert-srvtab-db b/contrib/convert-srvtab-db
index 74b19a7..8d3b31e 100755
--- a/contrib/convert-srvtab-db
+++ b/contrib/convert-srvtab-db
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-our $ID = q$Id$;
#
# convert-srvtab-db -- Converts a leland_srvtab database to wallet
#
diff --git a/contrib/used-principals b/contrib/used-principals
index f5abaf0..c4a6c07 100755
--- a/contrib/used-principals
+++ b/contrib/used-principals
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-our $ID = q$Id$;
#
# used-principals -- Report which Kerberos v5 principals are in use.
#
diff --git a/contrib/wallet-contacts b/contrib/wallet-contacts
new file mode 100755
index 0000000..a7bccf3
--- /dev/null
+++ b/contrib/wallet-contacts
@@ -0,0 +1,193 @@
+#!/usr/bin/perl -w
+#
+# wallet-contacts -- Report contact addresses for matching wallet objects.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2009 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+##############################################################################
+# Modules and declarations
+##############################################################################
+
+require 5.006;
+
+use strict;
+
+use Getopt::Long qw(GetOptions);
+use Wallet::Admin ();
+
+# Used to cache lookups of e-mail addresses by identifiers.
+our %EMAIL;
+
+##############################################################################
+# whois lookups
+##############################################################################
+
+# Given the directory handle of a user, look up their e-mail address. This
+# assumes the Stanford-specific swhois program.
+sub person_email {
+ my ($identifier) = @_;
+ return $EMAIL{$identifier} if exists $EMAIL{$identifier};
+ my @output = `swhois '$identifier'`;
+ for my $line (@output) {
+ if ($line =~ /^\s*Email:\s*(\S+)/i) {
+ $EMAIL{$identifier} = $1;
+ return $1;
+ } elsif ($line =~ /^\s*SUNet IDs:\s*(\S+)/) {
+ my $email = $1 . '@stanford.edu';
+ $EMAIL{$identifier} = $email;
+ return $email;
+ }
+ }
+ warn "$0: unable to find email address for identifier $identifier\n";
+ $EMAIL{$identifier} = undef;
+ return;
+}
+
+# Look up a system in whois and return the e-mail address or addresses of the
+# administrator.
+sub whois_lookup {
+ my ($system) = @_;
+ my @output = `swhois '$system'`;
+ my ($inadmin, @users, @admins);
+ for (@output) {
+ if (/^\s*administrator:\s*(?:\S+\s+)+\((d\S+)\)\s*$/i) {
+ push (@admins, person_email ($1));
+ $inadmin = 1;
+ } elsif (/^\s*administrator:/i) {
+ $inadmin = 1;
+ } elsif (/^\s*group:/i) {
+ $inadmin = 0;
+ } elsif ($inadmin and /^\s*e-?mail: (\S+)/i) {
+ push (@admins, $1);
+ } elsif ($inadmin and /^\s*(?:\S+\s+)+\((d\S+)\)\s*$/i) {
+ push (@admins, person_email ($1));
+ } elsif (/^\s*user:\s*(?:\S+\s+)+\((d\S+)\)\s*$/i) {
+ push (@users, person_email ($1));
+ }
+ }
+ @admins = @users if !@admins;
+ warn "$0: unable to find administrator for $system\n" unless @admins;
+ return @admins;
+}
+
+##############################################################################
+# Main routine
+##############################################################################
+
+# Read in command-line options.
+my ($help);
+Getopt::Long::config ('no_ignore_case', 'bundling');
+GetOptions ('help|h' => \$help) or exit 1;
+if ($help) {
+ print "Feeding myself to perldoc, please wait....\n";
+ exec ('perldoc', '-t', $0);
+}
+my ($type, $name) = @ARGV;
+if (@ARGV > 2 or not defined $name) {
+ die "Usage: wallet-contacts <type> <name>\n";
+}
+
+# Clean up $0 for error reporting.
+$0 =~ s%.*/%%;
+
+# Gather the list of ACL lines.
+my $admin = Wallet::Admin->new;
+my @lines = $admin->report_owners ($type, $name);
+if (!@lines and $admin->error) {
+ die $admin->error, "\n";
+}
+
+# Now, for each line, turn it into an e-mail address. krb5 ACLs go as-is if
+# they are regular user principals. If they're other principals, ignore them
+# unless they're of the form host/*, in which case extract the host and treat
+# it the same as a netdb ACL. netdb and netdb-root ACLs result in a whois
+# lookup on that host, extracting the e-mail address of the administrator
+# group. If there is no e-mail address, extract the user and look up their
+# e-mail address.
+my @email;
+for (@lines) {
+ my ($scheme, $identifier) = @$_;
+ my $machine;
+ if ($scheme eq 'krb5') {
+ if ($identifier =~ m,^[^/]+\@,) {
+ push (@email, $identifier);
+ } elsif ($identifier =~ m,^host/([^/]+)\@,) {
+ $machine = $1;
+ }
+ } elsif ($scheme eq 'netdb' or $scheme eq 'netdb-root') {
+ $machine = $identifier;
+ }
+ if ($machine) {
+ push (@email, whois_lookup ($machine));
+ }
+}
+
+# We now have a list of e-mail addresses. De-duplicate and then print them
+# out.
+my %seen;
+@email = grep { !$seen{$_}++ } sort @email;
+print join ("\n", @email, '');
+
+##############################################################################
+# Documentation
+##############################################################################
+
+=head1 NAME
+
+wallet-contacts - Report contact addresses for matching wallet objects
+
+=head1 SYNOPSIS
+
+B<wallet-contacts> [B<-h>] I<type-pattern> I<name-pattern>
+
+=head1 DESCRIPTION
+
+B<wallet-contacts> returns a list of e-mail addresses corresponding to
+members of owner ACLs for all objects in the wallet database matching
+I<type-pattern> and I<name-pattern>. The patterns can be wallet object
+types or names, or they can be SQL patterns using C<%> as a wildcard.
+
+C<krb5> ACL schemes will return the corresponding identifier as an e-mail
+address unless it contains a C</>. If it contains C</>, it will be
+ignored except for principals of the form C<host/I<hostname>>, which will
+have I<hostname> treated as if it were the identifier in a C<netdb> ACL.
+
+C<netdb> and C<netdb-root> ACL schemes will return the e-mail address from
+a whois lookup of the corresponding NetDB object. B<wallet-contacts> will
+run B<whois> on the system name and search the output for users and
+administrators. E-mail addresses for admin groups will be returned as-is.
+Administrators will result in a second lookup via B<swhois> for their
+directory handle, returning the corresponding e-mail address if found in
+their whois record. If there are no administrators or admin teams with
+e-mail addresses, the value of the user key, if any, will be looked up
+similar to an administrator.
+
+If B<wallet-contacts> is unable to find any contact for a host or any
+e-mail address for an administrator or user, it will warn but continue.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-h>, B<--help>
+
+Print out this documentation (which is done simply by feeding the script
+to C<perldoc -t>).
+
+=back
+
+=head1 CAVEATS
+
+Many of the assumptions made by this script are Stanford-specific, such as
+the ability to use Kerberos principals as-is as e-mail addresses, the
+B<swhois> program for looking up people, and the parsing of the B<whois>
+output format.
+
+=head1 AUTHOR
+
+Russ Allbery <rra@stanford.edu>
+
+=cut
diff --git a/contrib/wallet-report b/contrib/wallet-summary
index 6f09914..7a51f9e 100755
--- a/contrib/wallet-report
+++ b/contrib/wallet-summary
@@ -1,10 +1,9 @@
#!/usr/bin/perl -w
-$ID = q$Id$;
#
-# wallet-report -- Report on keytabs in the wallet database.
+# wallet-summarize -- Summarize keytabs in the wallet database.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2003, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2003, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -41,7 +40,7 @@ $ADDRESS = 'nobody@example.com';
require 5.005;
use strict;
-use vars qw($ADDRESS $DUMPFILE $ID @PATTERNS $REPORTS);
+use vars qw($ADDRESS $DUMPFILE @PATTERNS $REPORTS);
use Getopt::Long qw(GetOptions);
use File::Path qw(mkpath);
@@ -55,10 +54,10 @@ use Wallet::Admin ();
# Return a list of keytab objects in the wallet database. Currently, we only
# report on keytab objects; reports for other objects will be added later.
sub list_keytabs {
- my $admin = Wallet::Admin->new;
- my @objects = $admin->list_objects;
- if (!@objects and $admin->error) {
- die $admin->error;
+ my $report = Wallet::Report->new;
+ my @objects = $report->objects;
+ if (!@objects and $report->error) {
+ die $report->error;
}
return map { $$_[1] } grep { $$_[0] eq 'keytab' } @objects;
}
@@ -177,11 +176,11 @@ close REPORT;
=head1 NAME
-wallet-report - Report on keytabs in the wallet database
+wallet-summary - Report on keytabs in the wallet database
=head1 SYNOPSIS
-wallet-report [B<-hm>]
+B<wallet-summary> [B<-hm>]
=head1 DESCRIPTION
@@ -190,8 +189,8 @@ report of the types of principals contained therein and the total number
of principals registered. This report is sent to standard output by
default, but see B<-m> below.
-The classifications of srvtabs are determined by a set of patterns at the
-beginning of this script. Modify it to add new classifications.
+The classifications of principals are determined by a set of patterns at
+the beginning of this script. Modify it to add new classifications.
=head1 OPTIONS
diff --git a/contrib/wallet-summary.8 b/contrib/wallet-summary.8
new file mode 100644
index 0000000..088f307
--- /dev/null
+++ b/contrib/wallet-summary.8
@@ -0,0 +1,179 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "WALLET-SUMMARY 8"
+.TH WALLET-SUMMARY 8 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+wallet\-summary \- Report on keytabs in the wallet database
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBwallet-summary\fR [\fB\-hm\fR]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+Obtains a list of keytab objects in the wallet database and produces a
+report of the types of principals contained therein and the total number
+of principals registered. This report is sent to standard output by
+default, but see \fB\-m\fR below.
+.PP
+The classifications of principals are determined by a set of patterns at
+the beginning of this script. Modify it to add new classifications.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fB\-h\fR, \fB\-\-help\fR" 4
+.IX Item "-h, --help"
+Print out this documentation (which is done simply by feeding the script to
+\&\f(CW\*(C`perldoc \-t\*(C'\fR).
+.IP "\fB\-m\fR, \fB\-\-mail\fR" 4
+.IX Item "-m, --mail"
+Rather than printing the report to standard output, send the report via
+e\-mail to the address set at the beginning of this script and also archive
+a copy under \fI/afs/ir/dept/itss/infrastructure/reports\fR.
+.SH "FILES"
+.IX Header "FILES"
+.IP "\fI/afs/ir/dept/itss/infrastructure/reports\fR" 4
+.IX Item "/afs/ir/dept/itss/infrastructure/reports"
+The root directory for archived reports. Archived reports will be saved
+under this directory in a subdirectory for the year, the month, and
+\&\f(CW\*(C`kerberos\*(C'\fR, under the name \f(CW\*(C`wallet\*(C'\fR. In other words, for a report run
+in March of 2003, the report will be saved in the file:
+.Sp
+.Vb 1
+\& /afs/ir/dept/itss/infrastructure/reports/2003/03/kerberos/srvtabs
+.Ve
+.SH "NOTES"
+.IX Header "NOTES"
+Considerably more information could potentially be reported than is
+currently here. In particular, keytabs that have never been downloaded
+are not distinguished from those that have, the number of keytabs
+downloaded is not separately reported, and there aren't any statistics on
+how recently the keytabs were downloaded. These could be useful areas of
+future development.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>
diff --git a/docs/setup b/docs/setup
index ac83949..5a0036f 100644
--- a/docs/setup
+++ b/docs/setup
@@ -64,10 +64,10 @@ Wallet Configuration
On the wallet server, install remctld. Then, install the
configuration fragment in config/wallet in the remctld configuration.
- You can do this either by adding the one non-comment line of that file
- to your remctl.conf or, if your remctl.conf includes a directory of
- configuration fragments, drop config/wallet into that directory. You
- may need to change the path to wallet-backend.
+ You can do this either by adding the two non-comment lines of that
+ file to your remctl.conf or, if your remctl.conf includes a directory
+ of configuration fragments, drop config/wallet into that directory.
+ You may need to change the path to wallet-backend.
Note that the default wallet configuration allows any authenticated
user to run the wallet backend and relies on the wallet's ACLs for all
diff --git a/docs/stanford-naming b/docs/stanford-naming
index f887a69..f2a45a7 100644
--- a/docs/stanford-naming
+++ b/docs/stanford-naming
@@ -70,13 +70,6 @@ Object Naming
Then, we use the following naming conventions for different types of
objects:
- <group>-<service>-db-<name>
-
- Stores the database password for the database named <name>. This
- may be a file containing only the database password or a Perl
- AppConfig configuration file with the database connection
- information including the password.
-
<group>-<server>-htpasswd-<app>
An .htpasswd file for HTTP Basic Authentication for special-case
@@ -109,6 +102,30 @@ Object Naming
The public certificate we manage external to wallet since it
doesn't need to be protected or encrypted.
+ <group>-<server>-tivoli-key
+
+ The Tivoli backup encryption key for this server. This is stored
+ in the same file as the password used to connect to the Tivoli
+ server, so both are stored together. This file is found at
+ /etc/adsm/TSM.PWD. It must be base64-encoded before being stored
+ in the wallet.
+
+ <group>-<service>-config-<name>
+
+ A configuration file named <name> that contains some secure
+ information, such as a database password. Ideally, the secure
+ data should be stored in a separate file and assembled into the
+ configuration file, but that isn't always the path of least
+ resistance. Only use this naming convention if there is not a
+ more specific one below.
+
+ <group>-<service>-db-<name>
+
+ Stores the database password for the database named <name>. This
+ may be a file containing only the database password or a Perl
+ AppConfig configuration file with the database connection
+ information including the password.
+
<group>-<service>-gpg-key
Stores the GnuPG private key for a service that needs to do GnuPG
@@ -122,6 +139,13 @@ Object Naming
sometimes it's too hard to separate out chunks of a properties
file.
+ <group>-<service>-puppetconf
+
+ A puppet.conf configuration file for Puppet that contains some
+ secure data (such as SSL key passwords or database passwords).
+ Ideally the secure data should be stored in separate files, but
+ Puppet likes to use a single configuration file.
+
<group>-<service>-shibboleth
The shibboleth.xml configuration file for a service, when it
diff --git a/examples/stanford.conf b/examples/stanford.conf
index 05ca861..becfc6e 100644
--- a/examples/stanford.conf
+++ b/examples/stanford.conf
@@ -1,5 +1,4 @@
# /etc/wallet/wallet.conf -- Wallet system configuration. -*- perl -*-
-# $Id$
#
# Configuration for the wallet system as used at Stanford University.
# Interesting features to note are loading the database password from an
@@ -27,6 +26,7 @@ $DB_PASSWORD = <PASS>;
close PASS;
chomp $DB_PASSWORD;
+$KEYTAB_KRBTYPE = 'MIT';
$KEYTAB_FILE = '/etc/wallet/keytab';
$KEYTAB_FLAGS = '-clearpolicy';
$KEYTAB_HOST = 'krb5-admin.stanford.edu';
diff --git a/kasetkey/README b/kasetkey/README
deleted file mode 100644
index 033caff..0000000
--- a/kasetkey/README
+++ /dev/null
@@ -1,15 +0,0 @@
-$Id$
-
-This program used to be called gen_srvtab and was the backend used by the
-old sysctl-based srvtab distribution system. It can either load a key
-from a srvtab and push it into the AFS kaserver or generate a random key,
-push it into the AFS kaserver, and then write it out as a srvtab. It has
-a lot of strange issues (such as deleting and then recreating keys rather
-than changing the key and incrementing the kvno), but it works.
-
-This program only works with the AFS kaserver and requires the AFS
-libraries to compile.
-
-I haven't yet done the work to make compilation optional based on whether
-one wants to build kaserver support (or worked out how that will be
-configured in general). That's for later.
diff --git a/kasetkey/kasetkey.c b/kasetkey/kasetkey.c
deleted file mode 100644
index d40a9bb..0000000
--- a/kasetkey/kasetkey.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/* $Id$
- *
- * Create or change a principal and/or generate a srvtab.
- *
- * Sets the key of a principal in the AFS kaserver given a srvtab, enables or
- * disables a principal, or displays information about a principal in an AFS
- * kaserver.
- *
- * Written by Roland Schemers <schemers@stanford.edu>
- * Updated by Russ Allbery <rra@stanford.edu>
- * Updated again by Anton Ushakov <antonu@stanford.edu>
- * Copyright 1994, 1998, 1999, 2000, 2006, 2007, 2008
- * Board of Trustees, Leland Stanford Jr. University
- *
- * See LICENSE for licensing terms.
- */
-
-#include <config.h>
-#include <portable/system.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_KERBEROSIV_KRB_H
-# include <kerberosIV/krb.h>
-#else
-# include <krb.h>
-#endif
-
-#include <afs/stds.h>
-#include <afs/kauth.h>
-#include <afs/kautils.h>
-#include <afs/cellconfig.h>
-#include <ubik.h>
-
-#include <util/util.h>
-
-/* Normally set by the AFS libraries. */
-#ifndef SNAME_SZ
-# define SNAME_SZ 40
-# define INST_SZ 40
-# define REALM_SZ 40
-#endif
-
-/*
- * AFS currently doesn't prototype this function. Cheat on the first argument
- * since it actually takes a function with a completely variable argument
- * list.
- */
-#if !HAVE_DECL_UBIK_CALL
-afs_int32 ubik_Call(void *, struct ubik_client *, afs_int32, ...);
-#endif
-
-/* The name of the program, for error reporting. */
-static const char *program = NULL;
-
-/* Some global state information. */
-struct config {
- char *local_cell;
- int debug; /* Whether to enable debugging. */
- int init; /* Keyfile initialization. */
- int random; /* Randomize the key. */
- int tgs; /* Enable the principal. */
- int notgs; /* Disable the princial. */
- char *keyfile; /* Name of srvtab to use. */
- char *admin; /* Name of ADMIN user to use. */
- char *password; /* Password to use. */
- char *srvtab; /* srvtab file to generate. */
- char *service; /* Principal to create/enable. */
- char *delete; /* Principal to delete. */
- char *examine; /* Principal to examine. */
- char *k5srvtab; /* K5 converted srvtab to read for key. */
-};
-
-/* Usage message. Pass in the program name four times. */
-static const char usage_message[] = "\
-Usage: %s [options]\n\
- -a adminuser Admin user\n\
- -c k5srvtab Use the key from the given srvtab (for sync w/ K5)\n\
- -D service Name of service to delete\n\
- -d Turn on debugging\n\
- -e principal Examine the given principal\n\
- -f srvtab Name of srvtab file to create\n\
- -h This help\n\
- -i Initialize DES key file\n\
- -k keyfile File containing srvtab for admin user\n\
- -n Set the principal NOTGS\n\
- -p password Use given password to create key\n\
- -r Use random key\n\
- -s service Name of service to create\n\
- -t Set the principal TGS\n\
- -v Print version\n\
-\n\
-To create a srvtab for rcmd.slapshot and be prompted for the admin\n\
-passowrd:\n\
-\n\
- %s -f srvtab.rcmd.slapshot -s rcmd.slapshot -r\n\
-\n\
-To create a srvtab from within a script you must stash the DES key\n\
-in a srvtab with:\n\
-\n\
- %s -a admin -i -k /.adminkey\n\
-\n\
-and then create a srvtab for rcmd.slapshot with:\n\
-\n\
- %s -k /.adminkey -a admin -r -f srvtab -s rcmd.slapshot\n\
-\n";
-
-
-/*
- * Print out the usage message and then exit with the status given as the only
- * argument. If status is zero, the message is printed to standard output;
- * otherwise, it is sent to standard error.
- */
-static void
-usage(int status)
-{
- if (program == NULL)
- program = "";
- fprintf((status == 0) ? stdout : stderr, usage_message,
- program, program, program, program);
- exit(status);
-}
-
-
-/*
- * Parse a principal name into name, inst, and cell, filling in the cell from
- * local_cell if none was given. cell here is actually a realm and shouldn't
- * need any further conversion.
- */
-static void
-parse_principal(struct config *config, char *principal, char *name,
- char *inst, char *cell)
-{
- long code;
- int local;
-
- code = ka_ParseLoginName(principal, name, inst, cell);
- if (config->debug)
- printf("ka_ParseLoginName %ld\n", code);
- if (code != 0)
- die("can't parse principal %s", principal);
- if (cell[0] == '\0') {
- if (ka_CellToRealm(config->local_cell, cell, &local) == KANOCELL)
- die("unable to determine realm from local cell");
- }
-}
-
-
-/*
- * Given a srvtab file name, the principal, the kvno, and the key, write out a
- * new srvtab file. Dies on any error.
- */
-static void
-write_srvtab(const char *filename, const char *name, const char *inst,
- char *cell, unsigned char kvno, struct ktc_encryptionKey *key)
-{
- int fd;
-
- fd = open(filename, O_WRONLY | O_CREAT, 0600);
- if (fd == -1)
- sysdie("can't create srvtab %s", filename);
- if (write(fd, name, strlen(name) + 1) != (ssize_t) strlen(name) + 1)
- sysdie("can't write to srvtab %s", filename);
- if (write(fd, inst, strlen(inst) + 1) != (ssize_t) strlen(inst) + 1)
- sysdie("can't write to srvtab %s", filename);
- if (write(fd, cell, strlen(cell) + 1) != (ssize_t) strlen(cell) + 1)
- sysdie("can't write to srvtab %s", filename);
- if (write(fd, &kvno, 1) != 1)
- sysdie("can't write to srvtab %s", filename);
- if (write(fd, key, sizeof(*key)) != sizeof(*key))
- sysdie("can't write to srvtab %s", filename);
- if (close(fd) != 0)
- sysdie("can't close srvtab %s", filename);
-}
-
-
-/*
- * Initialize a DES keyfile from a password. If the password wasn't given via
- * a command-line option, prompt for it.
- */
-static void
-initialize_admin_srvtab(struct config *config)
-{
- struct ktc_encryptionKey key;
- char name[MAXKTCNAMELEN];
- char inst[MAXKTCNAMELEN];
- char cell[MAXKTCNAMELEN];
- long code;
-
- if (config->keyfile == NULL || config->admin == NULL)
- usage(1);
-
- /* Get the password, one way or another. */
- parse_principal(config, config->admin, name, inst, cell);
- if (config->password != NULL) {
- ka_StringToKey(config->password, cell, &key);
- memset(config->password, 0, strlen(config->password));
- } else {
- char buffer[MAXKTCNAMELEN * 3 + 40];
-
- sprintf(buffer,"password for %s: ", config->admin);
- code = ka_ReadPassword(buffer, 1, cell, &key);
- if (code != 0)
- die("can't read password");
- }
-
- /* Create the admin srvtab, removing any old one if one exists. */
- unlink(config->keyfile);
- write_srvtab(config->keyfile, name, inst, cell, 0, &key);
- exit(0);
-}
-
-
-/*
- * Takes the configuration struct and obtains an admin token, which it stores
- * in the second parameter. Dies on any failure.
- */
-static void
-authenticate(struct config *config, struct ktc_token *token)
-{
- char name[MAXKTCNAMELEN];
- char inst[MAXKTCNAMELEN];
- char cell[MAXKTCNAMELEN];
- long code;
- struct ktc_encryptionKey key;
-
- /* Get the admin password one way or the other. */
- parse_principal(config, config->admin, name, inst, cell);
- if (config->keyfile) {
- code = read_service_key(name, inst, cell, 0, config->keyfile,
- (char *) &key);
- if (config->debug)
- printf("read_service_key %ld\n", code);
- if (code != 0)
- die("can't get key for %s.%s@%s from srvtab %s", name, inst,
- cell, config->keyfile);
- } else {
- char buffer[MAXKTCNAMELEN * 3 + 40];
-
- sprintf(buffer, "password for %s: ", config->admin);
- code = ka_ReadPassword(buffer, 0, cell, &key);
- if (code)
- die("can't read password");
- }
-
- /* Now, get the admin token. */
- code = ka_GetAdminToken(name, inst, cell, &key, 300, token, 1);
- memset(&key, 0, sizeof(key));
- if (config->debug)
- printf("ka_GetAdminToken %ld\n", code);
- if (code != 0)
- die("can't get admin token");
-}
-
-
-/*
- * Delete a principal out of the AFS kaserver.
- */
-static void
-delete_principal(struct config *config)
-{
- struct ktc_token token;
- struct ubik_client *conn;
- char name[MAXKTCNAMELEN];
- char inst[MAXKTCNAMELEN];
- char cell[MAXKTCNAMELEN];
- long code;
-
- /* Make connection to AuthServer. */
- authenticate(config, &token);
- parse_principal(config, config->delete, name, inst, cell);
- code = ka_AuthServerConn(cell, KA_MAINTENANCE_SERVICE, &token, &conn);
- if (config->debug)
- printf("ka_AuthServerConn %s %ld\n", cell, code);
- if (code != 0)
- die("can't make connection to auth server");
-
- /* Delete the user. */
- code = ubik_Call(KAM_DeleteUser, conn, 0, name, inst);
- if (config->debug)
- printf("ubik_Call KAM_DeleteUser %ld\n", code);
- if (code != 0 && code != KANOENT)
- die("can't delete existing instance");
- code = ubik_ClientDestroy(conn);
- exit(0);
-}
-
-
-/*
- * Format a date. The output format expects ctime-style date formatting, so
- * we use that. Takes a buffer into which to put the date. There will be a
- * trailing newline.
- */
-static void
-format_date(char *buffer, size_t size, time_t date)
-{
- if (date == (time_t) NEVERDATE)
- strlcpy(buffer, "never\n", size);
- else
- strlcpy(buffer, ctime(&date), size);
-}
-
-
-/*
- * Enable or disable a principal in the AFS kaserver (by setting or clearing
- * the NOTGS flag). The second argument says to enable if it's true, disable
- * otherwise.
- */
-static void
-enable_principal(struct config *config, int enable)
-{
- struct ktc_token token;
- struct ubik_client *conn;
- struct kaentryinfo entry;
- char name[MAXKTCNAMELEN];
- char inst[MAXKTCNAMELEN];
- char cell[MAXKTCNAMELEN];
- long code;
-
- /* Make connection to AuthServer. */
- authenticate(config, &token);
- parse_principal(config, config->service, name, inst, cell);
- code = ka_AuthServerConn(cell, KA_MAINTENANCE_SERVICE, &token, &conn);
- if (config->debug)
- printf("ka_AuthServerConn %s %ld\n", cell, code);
- if (code != 0)
- die("can't make connection to auth server");
-
- /* Retrieve the principal information. */
- code = ubik_Call(KAM_GetEntry, conn, 0, name, inst, KAMAJORVERSION,
- &entry);
- if (config->debug)
- printf("ubik_Call KAM_GetEntry %ld\n", code);
- if (code != 0)
- die("can't retrieve current flags");
-
- /* Set the flags. */
- if (enable)
- entry.flags &= ~KAFNOTGS;
- else
- entry.flags |= KAFNOTGS;
- code = ubik_Call(KAM_SetFields, conn, 0, name, inst, entry.flags, 0, 0,
- -1, 0, 0);
- if (config->debug)
- printf("ubik_Call KAM_SetFields %ld\n", code);
- if (code != 0)
- die("can't %s principal", enable ? "enable" : "disable");
- code = ubik_ClientDestroy(conn);
- exit(0);
-}
-
-
-/*
- * Examine a principal. The output format is compatible with the old Stanford
- * Kerberos v4 kadmin, which may be compatible with Kerberos v4 kadmin in
- * general (I haven't checked).
- */
-static void
-examine_principal(struct config *config)
-{
- struct ktc_token token;
- struct ubik_client *conn;
- struct kaentryinfo entry;
- char name[MAXKTCNAMELEN];
- char inst[MAXKTCNAMELEN];
- char cell[MAXKTCNAMELEN];
- long code;
- char edate[64], cdate[64], mdate[64];
-
- /* Make connection to AuthServer. */
- authenticate(config, &token);
- parse_principal(config, config->examine, name, inst, cell);
- code = ka_AuthServerConn(cell, KA_MAINTENANCE_SERVICE, &token, &conn);
- if (config->debug)
- printf("ka_AuthServerConn %s %ld\n", cell, code);
- if (code != 0)
- die("can't make connection to auth server");
-
- /* Retrieve and format the entry. */
- code = ubik_Call(KAM_GetEntry, conn, 0, name, inst, KAMAJORVERSION,
- &entry);
- if (config->debug)
- printf("ubik_Call KAM_GetEntry %ld\n", code);
- if (code != 0) {
- if (code == KANOENT)
- die("no such entry in the database");
- else
- die("can't retrieve principal information");
- }
- format_date(edate, sizeof(edate), entry.user_expiration);
- format_date(mdate, sizeof(cdate), entry.modification_time);
- format_date(cdate, sizeof(mdate), entry.change_password_time);
- printf("status: %s\n", (entry.flags & KAFNOTGS) ? "disabled" : "enabled");
- printf("account expiration: %s", edate);
- printf("password last changed: %s", cdate);
- printf("modification time: %s", mdate);
- printf("modified by: %s%s%s\n", entry.modification_user.name,
- (entry.modification_user.instance[0] != '\0') ? "." : "",
- entry.modification_user.instance);
- code = ubik_ClientDestroy(conn);
- exit(0);
-}
-
-
-/*
- * Create a new principal in the AFS kaserver (deleting it and recreating it
- * if it already exists) with either the indicated key or with a random key,
- * and then write out a srvtab for that principal. Also supported is reading
- * the key from an existing srvtab (likely created via Kerberos v5 kadmin from
- * a keytab).
- */
-static void
-generate_srvtab(struct config *config)
-{
- struct ktc_token token;
- struct ubik_client *conn;
- char name[MAXKTCNAMELEN];
- char inst[MAXKTCNAMELEN];
- char cell[MAXKTCNAMELEN];
- long code;
- struct ktc_encryptionKey key;
-
- /* Make connection to AuthServer. */
- authenticate(config, &token);
- parse_principal(config, config->service, name, inst, cell);
- code = ka_AuthServerConn(cell, KA_MAINTENANCE_SERVICE, &token, &conn);
- if (config->debug)
- printf("ka_AuthServerConn %s %ld\n", cell, code);
- if (code != 0)
- die("can't make connection to auth server");
-
- /* Get the key for the principal we're creating. */
- if (config->k5srvtab != NULL) {
- char buffer[SNAME_SZ * 4];
- char *p;
- char sname[SNAME_SZ];
- char sinst[INST_SZ];
- char srealm[REALM_SZ];
- unsigned char kvno;
- FILE *srvtab;
-
- /* Read the whole converted srvtab into memory. */
- srvtab = fopen(config->k5srvtab, "r");
- if (srvtab == NULL)
- sysdie("can't open converted srvtab %s", config->k5srvtab);
- if (fgets(buffer, sizeof(buffer), srvtab) == NULL)
- sysdie("can't read converted srvtab %s", config->k5srvtab);
- fclose(srvtab);
-
- /* Now parse it. Fields are delimited by NUL. */
- p = buffer;
- strncpy(sname, p, SNAME_SZ - 1);
- sname[sizeof(sname) - 1] = '\0';
- p += strlen(sname) + 1;
- strncpy(sinst, p, INST_SZ - 1);
- sinst[sizeof(sinst) - 1] = '\0';
- p += strlen(sinst) + 1;
- strncpy(srealm, p, REALM_SZ - 1);
- srealm[sizeof(srealm) - 1] = '\0';
- p += strlen(srealm) + 1;
- memcpy(&kvno, p, sizeof(unsigned char));
- p += sizeof(unsigned char);
- memcpy(key.data, p, sizeof(key));
- memset(buffer, 0, sizeof(buffer));
- } else if (config->random) {
- code = ubik_Call(KAM_GetRandomKey, conn, 0, &key);
- if (config->debug)
- printf("ubik_Call KAM_GetRandomKey %ld\n", code);
- if (code != 0)
- die("can't get random key");
- } else {
- code = ka_ReadPassword((char *) "service password: ", 1, cell, &key);
- if (code != 0)
- die("can't read password");
- }
-
- /*
- * Now, we have the key. Try to create the principal. If it already
- * exists, try deleting it first and then creating it again.
- */
- code = ubik_Call(KAM_CreateUser, conn, 0, name, inst, key);
- if (config->debug)
- printf("ubik_Call KAM_CreateUser %ld\n", code);
- if (code == KAEXIST) {
- code = ubik_Call(KAM_DeleteUser, conn, 0, name, inst);
- if (config->debug)
- printf("ubik_Call KAM_DeleteUser %ld\n", code);
- if (code != 0)
- die("can't delete existing instance");
- code = ubik_Call(KAM_CreateUser, conn, 0, name, inst, key);
- if (config->debug)
- printf("ubik_Call KAM_CreateUser %ld\n", code);
- }
- if (code != 0)
- die("can't create user");
- code = ubik_ClientDestroy (conn);
-
- /* Create the srvtab file. Don't bother if we have a converted one. */
- if (config->srvtab && !config->k5srvtab) {
- unsigned char kvno = 0;
-
- /* Make a backup copy of any existing one, just in case. */
- if (access(config->srvtab, F_OK) == 0) {
- char backup[MAXPATHLEN];
-
- snprintf(backup, sizeof(backup), "%s.bak", config->srvtab);
- if (rename(config->srvtab, backup) != 0)
- sysdie("can't create backup srvtab %s", backup);
- }
- write_srvtab(config->srvtab, name, inst, cell, kvno, &key);
- }
- memset(&key, 0, sizeof(key));
- exit(0);
-}
-
-
-int
-main(int argc, char *argv[])
-{
- long code;
- int opt;
- struct config config;
-
- /* Initialize, get our local cell, etc. */
- memset(&config, 0, sizeof(config));
- code = ka_Init(0);
- config.local_cell = ka_LocalCell();
- if (config.local_cell == NULL || code != 0)
- die("can't initialize");
-
- /* Parse options. */
- while ((opt = getopt(argc, argv, "a:c:D:de:f:hik:np:rs:tv")) != EOF) {
- switch (opt) {
- case 'a': config.admin = optarg; break;
- case 'c': config.k5srvtab = optarg; break;
- case 'D': config.delete = optarg; break;
- case 'd': config.debug = 1; break;
- case 'e': config.examine = optarg; break;
- case 'f': config.srvtab = optarg; break;
- case 'i': config.init = 1; break;
- case 'k': config.keyfile = optarg; break;
- case 'n': config.notgs = 1; break;
- case 'p': config.password = optarg; break;
- case 'r': config.random = 1; break;
- case 's': config.service = optarg; break;
- case 't': config.tgs = 1; break;
-
- /* Usage doesn't return. */
- case 'h':
- usage(0);
- case 'v':
- printf("kasetkey %s\n", PACKAGE_VERSION);
- exit(0);
- default:
- usage(1);
- }
- }
-
- /* Take the right action. */
- if (config.random && config.k5srvtab)
- usage(1);
- if (config.notgs && config.tgs)
- die("cannot set principal both TGS and NOTGS at the same time");
- if ((config.notgs || config.tgs) && config.service == NULL)
- die("must specify a principal with -s");
- if (config.debug)
- fprintf(stdout, "cell: %s\n", config.local_cell);
- if (config.init)
- initialize_admin_srvtab(&config);
- else if (config.tgs || config.notgs)
- enable_principal(&config, config.tgs);
- else if (config.examine != NULL)
- examine_principal(&config);
- else if (config.service != NULL)
- generate_srvtab(&config);
- else if (config.delete != NULL)
- delete_principal(&config);
- else
- usage(1);
- exit(0);
-}
diff --git a/kasetkey/kasetkey.pod b/kasetkey/kasetkey.pod
deleted file mode 100644
index dcaa8b4..0000000
--- a/kasetkey/kasetkey.pod
+++ /dev/null
@@ -1,148 +0,0 @@
-=head1 NAME
-
-kasetkey - Manipulate AFS kaserver service principal keys
-
-=head1 SYNOPSIS
-
-B<kasetkey> [B<-dhv>] B<-a> I<admin> B<-i> [B<-p> I<password>]
- B<-k> I<keyfile>
-
-B<kasetkey> [B<-dhv>] B<-a> I<admin> [B<-k> I<keyfile>] B<-D> I<service>
-
-B<kasetkey> [B<-dhv>] B<-a> I<admin> [B<-k> I<keyfile>]
- [ B<-c> I<k5srvtab> | B<-r> ] B<-s> I<service> B<-f> I<srvtab>
-
-=head1 DESCRIPTION
-
-B<kasetkey> manipulates principals in an AFS kaserver, usually service
-principals. It's primarily designed for automatic generation of srvtabs
-for keys without regular passwords, but it can be used to do other
-automated tasks, authenticating from a srvtab.
-
-To start using B<kasetkey>, obtain a srvtab for a principal with the ADMIN
-flag set in the AFS kaserver. Such a srvtab can be created from the
-password of that principal using B<kasetkey> with the B<-i> flag. Then,
-use B<-s> to create a srvtab for a particular principal or B<-D> to delete
-a principal from the Kerberos database, passing via B<-k> the path to the
-srvtab containing the key for an ADMIN principal. If you don't use B<-k>,
-B<kasetkey> will prompt you for the password of the given ADMIN principal.
-
-When generating a srvtab for a particular principal using B<-s>, you have
-your choice of ways of setting the key for that principal. The default is
-to prompt you for a password, but usually that's not what you want.
-Provide the B<-r> flag to set a random key, which is normally what you
-want to do for a pure Kerberos v4 principal. When synchronizing Kerberos
-v5 with Kerberos v4, generate a keytab in Kerberos v5, convert it to a
-srvtab using B<ktutil>, and then provide that srvtab to B<kasetkey> with
-the B<-c> flag. B<kasetkey> will then set the key in the AFS kaserver to
-match.
-
-B<kasetkey> uses a simple, brute-force approach to setting keys in the AFS
-kaserver. It creates the principal if it doesn't already exist, and if it
-does already exist, it deletes it and then recreates it.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-a> I<admin>
-
-The user as whom changes should be performed. This user must have the
-ADMIN flag set in the AFS kaserver.
-
-=item B<-c> I<srvtab>
-
-When creating a service principal using B<-s>, take the key for that
-principal from I<srvtab>. I<srvtab> must contain a DES key and can be
-created via B<ktutil> from a Kerberos v5 keytab.
-
-=item B<-D> I<service>
-
-Delete the principal I<service> from the AFS kaserver.
-
-=item B<-d>
-
-Turn on debugging. This prints out more information about the exit status
-of all of the API calls used.
-
-=item B<-f> I<srvtab>
-
-Where to write the srvtab for a newly created (or modified) principal.
-Used only with B<-s>.
-
-=item B<-h>
-
-Display an option summary and a few examples and then exit.
-
-=item B<-i>
-
-Initialize a srvtab. Takes the user from B<-a> and either prompts for the
-password or takes it from the B<-p> flag. Writes out the srvtab to the
-path given to B<-k>.
-
-=item B<-k> I<srvtab>
-
-The srvtab to use to authenticate. The key in the srvtab must be the key
-for the user given with B<-a>.
-
-=item B<-p> I<password>
-
-The password for the user for which a srvtab is being initialized. This
-is only used with the B<-i> flag.
-
-=item B<-r>
-
-When generating a new srvtab with B<-s>, randomize the key for that user.
-
-=item B<-s> I<service>
-
-Create a new srvtab for the principal I<service>. If this principal
-already exists, it's deleted and recreated. Takes the key for the
-principal from the srvtab specified with B<-c>, randomizes it if B<-r> is
-given, or prompts for it.
-
-=item B<-v>
-
-Prints the version of B<kasetkey> and exits.
-
-=back
-
-=head1 EXAMPLES
-
-To create a srvtab for rcmd.slapshot and be prompted for the admin
-passowrd:
-
- kasetkey -f srvtab.rcmd.slapshot -s rcmd.slapshot -r
-
-To create a srvtab from within a script you must stash the DES key
-in a srvtab with:
-
- kasetkey -a admin -i -k /.adminkey
-
-(which will prompt you for the password) and then create a srvtab for
-rcmd.slapshot with:
-
- kasetkey -k /.adminkey -a admin -r -f srvtab -s rcmd.slapshot
-
-=head1 CAVEATS
-
-The error reporting of this program is not great. If an action fails, run
-it again with the B<-d> flag, which will print out the return status of
-every AFS operation. You can then pass the failing error code to the
-B<translate_et> program, installed with AFS, to translate the code into an
-error message.
-
-=head1 SEE ALSO
-
-kas(8), kaserver(8), ktutil(8)
-
-This program is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
-
-=head1 AUTHORS
-
-Originally written by Roland Schemers. Revised to use srvtabs rather than
-simple DES keys and to support principal deletion by Russ Allbery
-<rra@stanford.edu>, who currently maintains it.
-
-=cut
diff --git a/m4/gssapi.m4 b/m4/gssapi.m4
index 5c0d9e7..4b08569 100644
--- a/m4/gssapi.m4
+++ b/m4/gssapi.m4
@@ -1,31 +1,24 @@
-dnl gssapi.m4 -- Find the compiler and linker flags for GSS-API.
-dnl $Id$
+dnl Find the compiler and linker flags for GSS-API.
dnl
-dnl Finds the compiler and linker flags for linking with GSS-API libraries
-dnl and sets the substitution variables GSSAPI_CPPFLAGS, GSSAPI_LDFLAGS, and
-dnl GSSAPI_LIBS. Provides the --with-gssapi configure option to specify a
-dnl non-standard path to the GSS-API libraries. Uses krb5-config where
-dnl available unless reduced dependencies is requested.
+dnl Finds the compiler and linker flags for linking with GSS-API libraries.
+dnl Provides the --with-gssapi, --with-gssapi-include, and --with-gssapi-lib
+dnl configure option to specify a non-standard path to the GSS-API libraries.
+dnl Uses krb5-config where available unless reduced dependencies is requested.
dnl
dnl Provides the macro RRA_LIB_GSSAPI and sets the substitution variables
dnl GSSAPI_CPPFLAGS, GSSAPI_LDFLAGS, and GSSAPI_LIBS. Also provides
-dnl RRA_LIB_GSSAPI_SET to set CPPFLAGS, LDFLAGS, and LIBS to include the
-dnl GSS-API libraries; RRA_LIB_GSSAPI_SWITCH to do the same but save the
-dnl current values first; and RRA_LIB_GSSAPI_RESTORE to restore those settings
-dnl to before the last RRA_LIB_GSSAPI_SWITCH.
+dnl RRA_LIB_GSSAPI_SWITCH to set CPPFLAGS, LDFLAGS, and LIBS to include the
+dnl GSS-API libraries, saving the ecurrent values, and RRA_LIB_GSSAPI_RESTORE
+dnl to restore those settings to before the last RRA_LIB_GSSAPI_SWITCH.
+dnl
+dnl Depends on RRA_ENABLE_REDUCED_DEPENDS and RRA_SET_LDFLAGS.
dnl
dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2005, 2006, 2007, 2008
+dnl Copyright 2005, 2006, 2007, 2008, 2009
dnl Board of Trustees, Leland Stanford Jr. University
dnl
dnl See LICENSE for licensing terms.
-dnl Set CPPFLAGS, LDFLAGS, and LIBS to values including the GSS-API settings.
-AC_DEFUN([RRA_LIB_GSSAPI_SET],
-[CPPFLAGS="$GSSAPI_CPPFLAGS $CPPFLAGS"
- LDFLAGS="$GSSAPI_LDFLAGS $LDFLAGS"
- LIBS="$GSSAPI_LIBS $LIBS"])
-
dnl Save the current CPPFLAGS, LDFLAGS, and LIBS settings and switch to
dnl versions that include the GSS-API flags. Used as a wrapper, with
dnl RRA_LIB_GSSAPI_RESTORE, around tests.
@@ -33,7 +26,9 @@ AC_DEFUN([RRA_LIB_GSSAPI_SWITCH],
[rra_gssapi_save_CPPFLAGS="$CPPFLAGS"
rra_gssapi_save_LDFLAGS="$LDFLAGS"
rra_gssapi_save_LIBS="$LIBS"
- RRA_LIB_GSSAPI_SET])
+ CPPFLAGS="$GSSAPI_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$GSSAPI_LDFLAGS $LDFLAGS"
+ LIBS="$GSSAPI_LIBS $LIBS"])
dnl Restore CPPFLAGS, LDFLAGS, and LIBS to their previous values (before
dnl RRA_LIB_GSSAPI_SWITCH was called).
@@ -42,12 +37,18 @@ AC_DEFUN([RRA_LIB_GSSAPI_RESTORE],
LDFLAGS="$rra_gssapi_save_LDFLAGS"
LIBS="$rra_gssapi_save_LIBS"])
-dnl Set GSSAPI_CPPFLAGS and GSSAPI_LDFLAGS based on rra_gssapi_root.
+dnl Set GSSAPI_CPPFLAGS and GSSAPI_LDFLAGS based on rra_gssapi_root,
+dnl rra_gssapi_libdir, and rra_gssapi_includedir.
AC_DEFUN([_RRA_LIB_GSSAPI_PATHS],
-[AS_IF([test x"$rra_gssapi_root" != x],
- [AS_IF([test x"$rra_gssapi_root" != x/usr],
- [GSSAPI_CPPFLAGS="-I${rra_gssapi_root}/include"])
- GSSAPI_LDFLAGS="-L${rra_gssapi_root}/lib"])])
+[AS_IF([test x"$rra_gssapi_libdir" != x],
+ [GSSAPI_LDFLAGS="-L$rra_gssapi_libdir"],
+ [AS_IF([test x"$rra_gssapi_root" != x],
+ [RRA_SET_LDFLAGS([GSSAPI_LDFLAGS], [$rra_gssapi_root])])])
+ AS_IF([test x"$rra_gssapi_includedir" != x],
+ [GSSAPI_CPPFLAGS="-I$rra_gssapi_includedir"],
+ [AS_IF([test x"$rra_gssapi_root" != x],
+ [AS_IF([test x"$rra_gssapi_root" != x/usr],
+ [GSSAPI_CPPFLAGS="-I${rra_gssapi_root}/include"])])])])
dnl Does the appropriate library checks for reduced-dependency GSS-API
dnl linkage.
@@ -55,10 +56,13 @@ AC_DEFUN([_RRA_LIB_GSSAPI_REDUCED],
[RRA_LIB_GSSAPI_SWITCH
AC_CHECK_LIB([gssapi_krb5], [gss_import_name], [GSSAPI_LIBS="-lgssapi_krb5"],
[AC_CHECK_LIB([gssapi], [gss_import_name], [GSSAPI_LIBS="-lgssapi"],
- [AC_MSG_ERROR([cannot find usable GSS-API library])])])])
+ [AC_CHECK_LIB([gss], [gss_import_name], [GSSAPI_LIBS="-lgss"],
+ [AC_MSG_ERROR([cannot find usable GSS-API library])])])])])
dnl Does the appropriate library checks for GSS-API linkage when we don't
-dnl have krb5-config or reduced dependencies.
+dnl have krb5-config or reduced dependencies. libgss is used as a last
+dnl resort, since it may be a non-functional mech-independent wrapper, but
+dnl it's the right choice on Solaris 10.
AC_DEFUN([_RRA_LIB_GSSAPI_MANUAL],
[RRA_LIB_GSSAPI_SWITCH
rra_gssapi_extra=
@@ -92,53 +96,73 @@ AC_DEFUN([_RRA_LIB_GSSAPI_MANUAL],
rra_gssapi_extra="-lkrb5 $rra_gssapi_extra"
AC_CHECK_LIB([gssapi_krb5], [gss_import_name],
[GSSAPI_LIBS="-lgssapi_krb5 $rra_gssapi_extra"],
- [AC_MSG_ERROR([cannot find usable GSS-API library])],
+ [AC_CHECK_LIB([gss], [gss_import_name],
+ [GSSAPI_LIBS="-lgss"],
+ [AC_MSG_ERROR([cannot find usable GSS-API library])])],
[$rra_gssapi_extra])],
[-lkrb5 -lasn1 -lroken -lcrypto -lcom_err $rra_gssapi_extra])
RRA_LIB_GSSAPI_RESTORE])
dnl Sanity-check the results of krb5-config and be sure we can really link a
-dnl GSS-API program.
+dnl GSS-API program. If not, fall back on the manual check.
AC_DEFUN([_RRA_LIB_GSSAPI_CHECK],
[RRA_LIB_GSSAPI_SWITCH
- AC_CHECK_FUNC([gss_import_name], ,
- [AC_MSG_FAILURE([krb5-config results fail for GSS-API])])
- RRA_LIB_GSSAPI_RESTORE])
+ AC_CHECK_FUNC([gss_import_name],
+ [RRA_LIB_GSSAPI_RESTORE],
+ [RRA_LIB_GSSAPI_RESTORE
+ GSSAPI_CPPFLAGS=
+ GSSAPI_LIBS=
+ _RRA_LIB_GSSAPI_PATHS
+ _RRA_LIB_GSSAPI_MANUAL])])
dnl The main macro.
AC_DEFUN([RRA_LIB_GSSAPI],
[AC_REQUIRE([RRA_ENABLE_REDUCED_DEPENDS])
rra_gssapi_root=
+ rra_gssapi_libdir=
+ rra_gssapi_includedir=
GSSAPI_CPPFLAGS=
GSSAPI_LDFLAGS=
GSSAPI_LIBS=
AC_SUBST([GSSAPI_CPPFLAGS])
AC_SUBST([GSSAPI_LDFLAGS])
AC_SUBST([GSSAPI_LIBS])
+
AC_ARG_WITH([gssapi],
- [AC_HELP_STRING([--with-gssapi=DIR],
+ [AS_HELP_STRING([--with-gssapi=DIR],
[Location of GSS-API headers and libraries])],
[AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
[rra_gssapi_root="$withval"])])
+ AC_ARG_WITH([gssapi-include],
+ [AS_HELP_STRING([--with-gssapi-include=DIR],
+ [Location of GSS-API headers])],
+ [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
+ [rra_gssapi_includedir="$withval"])])
+ AC_ARG_WITH([gssapi-lib],
+ [AS_HELP_STRING([--with-gssapi-lib=DIR],
+ [Location of GSS-API libraries])],
+ [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
+ [rra_gssapi_libdir="$withval"])])
+
AS_IF([test x"$rra_reduced_depends" = xtrue],
[_RRA_LIB_GSSAPI_PATHS
_RRA_LIB_GSSAPI_REDUCED],
[AC_ARG_VAR([KRB5_CONFIG], [Path to krb5-config])
- AS_IF([test x"$rra_gssapi_root" != x],
+ AS_IF([test x"$rra_gssapi_root" != x && test -z "$KRB5_CONFIG"],
[AS_IF([test -x "${rra_gssapi_root}/bin/krb5-config"],
[KRB5_CONFIG="${rra_gssapi_root}/bin/krb5-config"])],
[AC_PATH_PROG([KRB5_CONFIG], [krb5-config])])
- AS_IF([test x"$KRB5_CONFIG" != x],
+ AS_IF([test x"$KRB5_CONFIG" != x && test -x "$KRB5_CONFIG"],
[AC_CACHE_CHECK([for gssapi support in krb5-config],
[rra_cv_lib_gssapi_config],
- [AS_IF(["$KRB5_CONFIG" | grep gssapi > /dev/null 2>&1],
+ [AS_IF(["$KRB5_CONFIG" 2>&1 | grep gssapi >/dev/null 2>&1],
[rra_cv_lib_gssapi_config=yes],
[rra_cv_lib_gssapi_config=no])])
AS_IF([test "$rra_cv_lib_gssapi_config" = yes],
- [GSSAPI_CPPFLAGS=`"$KRB5_CONFIG" --cflags gssapi`
- GSSAPI_LIBS=`"$KRB5_CONFIG" --libs gssapi`],
- [GSSAPI_CPPFLAGS=`"$KRB5_CONFIG" --cflags`
- GSSAPI_LIBS=`"$KRB5_CONFIG" --libs`])
+ [GSSAPI_CPPFLAGS=`"$KRB5_CONFIG" --cflags gssapi 2>/dev/null`
+ GSSAPI_LIBS=`"$KRB5_CONFIG" --libs gssapi 2>/dev/null`],
+ [GSSAPI_CPPFLAGS=`"$KRB5_CONFIG" --cflags 2>/dev/null`
+ GSSAPI_LIBS=`"$KRB5_CONFIG" --libs 2>/dev/null`])
GSSAPI_CPPFLAGS=`echo "$GSSAPI_CPPFLAGS" \
| sed 's%-I/usr/include ?%%'`
_RRA_LIB_GSSAPI_CHECK],
diff --git a/m4/kaserver.m4 b/m4/kaserver.m4
deleted file mode 100644
index 6a41bd4..0000000
--- a/m4/kaserver.m4
+++ /dev/null
@@ -1,95 +0,0 @@
-dnl kaserver.m4 -- Find the compiler and linker flags for OpenAFS kaserver.
-dnl $Id$
-dnl
-dnl If --with-kaserver is given, finds the compiler and linker flags for
-dnl building with OpenAFS libraries; sets AFS_CPPFLAGS, AFS_LDFLAGS, and
-dnl AFS_LIBS as appropriate; and defines HAVE_AFS. Provides the macro
-dnl RRA_LIB_AFS, which takes no arguments.
-dnl
-dnl This function also sets rra_kaserver to true if AFS was requested, which
-dnl can be checked to determine if further checks should be done.
-dnl
-dnl Also provides RRA_LIB_AFS_SET to set CPPFLAGS, LDFLAGS, and LIBS to
-dnl include the AFS libraries; RRA_LIB_AFS_SWITCH to do the same but save the
-dnl current values first; and RRA_LIB_AFS_RESTORE to restore those settings to
-dnl before the last RRA_LIB_AFS_SWITCH.
-dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Based on code developed by Derrick Brashear and Ken Hornstein of Sine
-dnl Nomine Associates, on behalf of Stanford University.
-dnl Copyright 2006, 2007, 2008
-dnl Board of Trustees, Leland Stanford Jr. University
-dnl
-dnl See LICENSE for licensing terms.
-
-dnl Set CPPFLAGS, LDFLAGS, and LIBS to values including the AFS settings.
-AC_DEFUN([RRA_LIB_AFS_SET],
-[CPPFLAGS="$AFS_CPPFLAGS $CPPFLAGS"
- LDFLAGS="$AFS_LDFLAGS $LDFLAGS"
- LIBS="$AFS_LIBS $LIBS"])
-
-dnl Save the current CPPFLAGS, LDFLAGS, and LIBS settings and switch to
-dnl versions that include the AFS flags. Used as a wrapper, with
-dnl RRA_LIB_AFS_RESTORE, around tests.
-AC_DEFUN([RRA_LIB_AFS_SWITCH],
-[rra_afs_save_CPPFLAGS="$CPPFLAGS"
- rra_afs_save_LDFLAGS="$LDFLAGS"
- rra_afs_save_LIBS="$LIBS"
- RRA_LIB_AFS_SET])
-
-dnl Restore CPPFLAGS, LDFLAGS, and LIBS to their previous values (before
-dnl RRA_LIB_AFS_SWITCH was called).
-AC_DEFUN([RRA_LIB_AFS_RESTORE],
-[CPPFLAGS="$rra_afs_save_CPPFLAGS"
- LDFLAGS="$rra_afs_save_LDFLAGS"
- LIBS="$rra_afs_save_LIBS"])
-
-dnl The function that does the work checking for the AFS libraries.
-AC_DEFUN([_RRA_LIB_AFS_CHECK],
-[RRA_LIB_AFS_SET
- LIBS=
- AC_SEARCH_LIBS([pthread_getspecific], [pthread])
- AC_SEARCH_LIBS([res_search], [resolv], ,
- [AC_SEARCH_LIBS([__res_search], [resolv])])
- AC_SEARCH_LIBS([gethostbyname], [nsl])
- AC_SEARCH_LIBS([socket], [socket], ,
- [AC_CHECK_LIB([nsl], [socket], [LIBS="-lnsl -lsocket $LIBS"], ,
- [-lsocket])])
- AFS_LIBS="$AFS_LIBS $LIBS"
- LIBS="$AFS_LIBS"
- AC_CACHE_CHECK([whether linking with AFS libraries work], [rra_cv_lib_afs],
- [AC_TRY_LINK(
-[#include <afs/param.h>
-#include <afs/kautils.h>],
-[char cell[256] = "EXAMPLE.COM";
-char realm[256];
-int local;
-
-ka_CellToRealm(cell, realm, &local);],
- [rra_cv_lib_afs=yes],
- [rra_cv_lib_afs=no])])
- AS_IF([test "$rra_cv_lib_afs" = no],
- [AC_MSG_ERROR([unable to link test AFS program])])
- RRA_LIB_AFS_RESTORE])
-
-dnl The public entry point. Sets up the --with option and only does the
-dnl library check if AFS linkage was requested.
-AC_DEFUN([RRA_LIB_AFS],
-[rra_afs=false
- AFS_CPPFLAGS=
- AFS_LDFLAGS=
- AFS_LIBS="-lafsauthent -lafsrpc"
- AC_SUBST([AFS_CPPFLAGS])
- AC_SUBST([AFS_LDFLAGS])
- AC_SUBST([AFS_LIBS])
- AC_ARG_WITH([kaserver],
- [AC_HELP_STRING([--with-kaserver@<:@=DIR@:>@],
- [Compile with AFS kaserver sync support])],
- [AS_IF([test x"$withval" != xno],
- [rra_afs=true
- AS_IF([test x"$withval" != xyes],
- [AFS_CPPFLAGS="-I${withval}/include"
- AFS_LDFLAGS="-L${withval}/lib"])
- _RRA_LIB_AFS_CHECK
- AC_DEFINE([HAVE_AFS], 1,
- [Define to enable AFS kaserver support.])])])])
diff --git a/m4/krb4.m4 b/m4/krb4.m4
deleted file mode 100644
index 321b0bf..0000000
--- a/m4/krb4.m4
+++ /dev/null
@@ -1,153 +0,0 @@
-dnl krb4.m4 -- Find the compiler and linker flags for Kerberos v4.
-dnl $Id$
-dnl
-dnl Finds the compiler and linker flags for linking with Kerberos v4 libraries
-dnl and sets the substitution variables KRB4_CPPFLAGS, KRB4_LDFLAGS, and
-dnl KRB4_LIBS. Provides the --with-krb4 configure option to specify a
-dnl non-standard path to the Kerberos libraries. Uses krb5-config where
-dnl available unless reduced dependencies is requested.
-dnl
-dnl Provides the macro RRA_LIB_KRB4 and sets the substitution variables
-dnl KRB4_CPPFLAGS, KRB4_LDFLAGS, and KRB4_LIBS. Also provides
-dnl RRA_LIB_KRB4_SET to set CPPFLAGS, LDFLAGS, and LIBS to include the
-dnl Kerberos libraries; RRA_LIB_KRB4_SWITCH to do the same but save the
-dnl current values first; and RRA_LIB_KRB4_RESTORE to restore those settings
-dnl to before the last RRA_LIB_KRB4_SWITCH.
-dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2005, 2006, 2007, 2008
-dnl Board of Trustees, Leland Stanford Jr. University
-dnl
-dnl See LICENSE for licensing terms.
-
-dnl Set CPPFLAGS, LDFLAGS, and LIBS to values including the Kerberos v4
-dnl settings.
-AC_DEFUN([RRA_LIB_KRB4_SET],
-[CPPFLAGS="$KRB4_CPPFLAGS $CPPFLAGS"
- LDFLAGS="$KRB4_LDFLAGS $LDFLAGS"
- LIBS="$KRB4_LIBS $LIBS"])
-
-dnl Save the current CPPFLAGS, LDFLAGS, and LIBS settings and switch to
-dnl versions that include the Kerberos v4 flags. Used as a wrapper, with
-dnl RRA_LIB_KRB4_RESTORE, around tests.
-AC_DEFUN([RRA_LIB_KRB4_SWITCH],
-[rra_krb4_save_CPPFLAGS="$CPPFLAGS"
- rra_krb4_save_LDFLAGS="$LDFLAGS"
- rra_krb4_save_LIBS="$LIBS"
- RRA_LIB_KRB4_SET])
-
-dnl Restore CPPFLAGS, LDFLAGS, and LIBS to their previous values (before
-dnl RRA_LIB_KRB4_SWITCH was called).
-AC_DEFUN([RRA_LIB_KRB4_RESTORE],
-[CPPFLAGS="$rra_krb4_save_CPPFLAGS"
- LDFLAGS="$rra_krb4_save_LDFLAGS"
- LIBS="$rra_krb4_save_LIBS"])
-
-dnl Set KRB4_CPPFLAGS and KRB4_LDFLAGS based on rra_krb4_root.
-AC_DEFUN([_RRA_LIB_KRB4_PATHS],
-[AS_IF([test x"$rra_krb4_root" != x],
- [AS_IF([test x"$rra_krb4_root" != x/usr],
- [KRB4_CPPFLAGS="-I${rra_krb4_root}/include"])
- KRB4_LDFLAGS="-L${rra_krb4_root}/lib"])])
-
-dnl Does the appropriate library checks for reduced-dependency Kerberos v4
-dnl linkage.
-AC_DEFUN([_RRA_LIB_KRB4_REDUCED],
-[RRA_LIB_KRB4_SWITCH
- AC_CHECK_LIB([krb4], [krb_get_svc_in_tkt], [KRB4_LIBS="-lkrb4"],
- [AC_CHECK_LIB([krb], [krb_get_svc_in_tkt], [KRB4_LIBS="-lkrb"],
- [AC_MSG_ERROR([cannot find usable Kerberos v4 library])])])
- RRA_LIB_KRB4_RESTORE])
-
-dnl Does the appropriate library checks for Kerberos v4 linkage when we don't
-dnl have krb5-config or reduced dependencies.
-AC_DEFUN([_RRA_LIB_KRB4_MANUAL],
-[RRA_LIB_KRB4_SWITCH
- rra_krb4_extra=
- LIBS=
- AC_SEARCH_LIBS([res_search], [resolv], ,
- [AC_SEARCH_LIBS([__res_search], [resolv])])
- AC_SEARCH_LIBS([gethostbyname], [nsl])
- AC_SEARCH_LIBS([socket], [socket], ,
- [AC_CHECK_LIB([nsl], [socket], [LIBS="-lnsl -lsocket $LIBS"], ,
- [-lsocket])])
- AC_SEARCH_LIBS([crypt], [crypt])
- rra_krb4_extra="$LIBS"
- LIBS="$rra_krb4_save_LIBS"
- AC_CHECK_LIB([crypto], [des_set_key],
- [rra_krb4_extra="-lcrypto $rra_krb4_extra"],
- [AC_CHECK_LIB([des], [des_set_key],
- [rra_krb4_extra="-ldes $rra_krb4_extra"])])
- AC_CHECK_LIB([krb], [krb_get_svc_in_tkt],
- [KRB4_LIBS="-lkrb $rra_krb4_extra"],
- [rra_krb4_extra="-ldes425 -lkrb5 -lk5crypto -lcom_err $rra_krb4_extra"
- AC_CHECK_LIB([krb5support], [krb5int_getspecific],
- [rra_krb4_extra="$rra_krb4_extra -lkrb5support"],
- [AC_CHECK_LIB([pthreads], [pthread_setspecific],
- [rra_krb4_pthread="-lpthreads"],
- [AC_CHECK_LIB([pthread], [pthread_setspecific],
- [rra_krb4_pthread="-lpthread"])])
- AC_CHECK_LIB([krb5support], [krb5int_setspecific],
- [rra_krb4_extra="-lkrb5support $rra_krb4_pthread"], ,
- [$rra_krb4_pthread])])
- AC_CHECK_LIB([krb4], [krb_get_svc_in_tkt],
- [KRB4_LIBS="-lkrb4 $rra_krb4_extra"],
- [AC_MSG_ERROR([cannot find usable Kerberos v4 library])],
- [$rra_krb4_extra])],
- [$rra_krb4_extra])
- RRA_LIB_KRB4_RESTORE])
-
-dnl Additional checks for portability that apply to either way that we find
-dnl the right libraries.
-AC_DEFUN([_RRA_LIB_KRB4_EXTRA],
-[RRA_LIB_KRB4_SWITCH
- AC_CHECK_HEADERS([kerberosIV/krb.h])
- RRA_LIB_KRB4_RESTORE])
-
-dnl Sanity-check the results of krb5-config and be sure we can really link a
-dnl Kerberos program.
-AC_DEFUN([_RRA_LIB_KRB4_CHECK],
-[RRA_LIB_KRB4_SWITCH
- AC_CHECK_FUNC([krb_get_svc_in_tkt], ,
- [AC_MSG_FAILURE([krb5-config results fail for Kerberos v4])])
- RRA_LIB_KRB4_RESTORE])
-
-dnl The main macro.
-AC_DEFUN([RRA_LIB_KRB4],
-[AC_REQUIRE([RRA_ENABLE_REDUCED_DEPENDS])
-rra_krb4_root=
-KRB4_CPPFLAGS=
-KRB4_LDFLAGS=
-KRB4_LIBS=
-AC_SUBST([KRB4_CPPFLAGS])
-AC_SUBST([KRB4_LDFLAGS])
-AC_SUBST([KRB4_LIBS])
-AC_ARG_WITH([krb4],
- [AC_HELP_STRING([--with-krb4=DIR],
- [Location of Kerberos v4 headers and libraries])],
- [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
- [rra_krb4_root="$withval"])])
-AS_IF([test x"$rra_reduced_depends" = xtrue],
- [_RRA_LIB_KRB4_PATHS
- _RRA_LIB_KRB4_REDUCED],
- [AC_ARG_VAR([KRB5_CONFIG], [Path to krb5-config])
- AS_IF([test x"$rra_krb4_root" != x && test -z "$KRB5_CONFIG"],
- [AS_IF([test -x "${rra_krb4_root}/bin/krb5-config"],
- [KRB5_CONFIG="${rra_krb4_root}/bin/krb5-config"])],
- [AC_PATH_PROG([KRB5_CONFIG], [krb5-config])])
- AS_IF([test x"$KRB5_CONFIG" != x && test -x "$KRB5_CONFIG"],
- [AC_CACHE_CHECK([for krb4 support in krb5-config],
- [rra_cv_lib_krb4_config],
- [AS_IF(["$KRB5_CONFIG" | grep krb4 > /dev/null 2>&1],
- [rra_cv_lib_krb4_config=yes],
- [rra_cv_lib_krb4_config=no])])
- AS_IF([test "$rra_cv_lib_krb4_config" = yes],
- [KRB4_CPPFLAGS=`"$KRB5_CONFIG" --cflags krb4`
- KRB4_LIBS=`"$KRB5_CONFIG" --libs krb4`],
- [_RRA_LIB_KRB4_PATHS
- _RRA_LIB_KRB4_MANUAL])
- KRB4_CPPFLAGS=`echo "$KRB5_CPPFLAGS" | sed 's%-I/usr/include ?%%'`
- _RRA_LIB_KRB4_CHECK],
- [_RRA_LIB_KRB4_PATHS
- _RRA_LIB_KRB4_MANUAL])])
- _RRA_LIB_KRB4_EXTRA])
diff --git a/m4/krb5.m4 b/m4/krb5.m4
index 934be0c..bba9694 100644
--- a/m4/krb5.m4
+++ b/m4/krb5.m4
@@ -1,42 +1,36 @@
-dnl krb5.m4 -- Find the compiler and linker flags for Kerberos v5.
-dnl $Id$
+dnl Find the compiler and linker flags for Kerberos v5.
dnl
-dnl Finds the compiler and linker flags for linking with Kerberos v5 libraries
-dnl and sets the substitution variables KRB5_CPPFLAGS, KRB5_LDFLAGS, and
-dnl KRB5_LIBS. Provides the --with-krb5 configure option to specify a
-dnl non-standard path to the Kerberos libraries. Uses krb5-config where
-dnl available unless reduced dependencies is requested.
-dnl
-dnl Sets an Automake conditional saying whether we use com_err, since if we're
-dnl also linking with AFS libraries, we may have to change library ordering in
-dnl that case.
+dnl Finds the compiler and linker flags for linking with Kerberos v5
+dnl libraries. Provides the --with-krb5, --with-krb5-include, and
+dnl --with-krb5-lib configure options to specify non-standards paths to the
+dnl Kerberos libraries. Uses krb5-config where available unless reduced
+dnl dependencies is requested.
dnl
dnl Provides the macro RRA_LIB_KRB5 and sets the substitution variables
dnl KRB5_CPPFLAGS, KRB5_LDFLAGS, and KRB5_LIBS. Also provides
-dnl RRA_LIB_KRB5_SET to set CPPFLAGS, LDFLAGS, and LIBS to include the
-dnl Kerberos libraries; RRA_LIB_KRB5_SWITCH to do the same but save the
-dnl current values first; and RRA_LIB_KRB5_RESTORE to restore those settings
-dnl to before the last RRA_LIB_KRB5_SWITCH.
+dnl RRA_LIB_KRB5_SWITCH to set CPPFLAGS, LDFLAGS, and LIBS to include the
+dnl Kerberos libraries, saving the current values first, and
+dnl RRA_LIB_KRB5_RESTORE to restore those settings to before the last
+dnl RRA_LIB_KRB5_SWITCH.
dnl
-dnl Also provides the RRA_LIB_KRB5_OPTIONAL macro, which should be used if
-dnl Kerberos support is optional. This macro will still always set the
-dnl substitution variables, but they'll be empty unless --with-krb5 is used.
-dnl Also, HAVE_KERBEROS will be defined if --with-krb5 is given and
+dnl Provides the RRA_LIB_KRB5_OPTIONAL macro, which should be used if Kerberos
+dnl support is optional. This macro will still always set the substitution
+dnl variables, but they'll be empty unless --with-krb5 is given. Also,
+dnl HAVE_KERBEROS will be defined if --with-krb5 is given and
dnl $rra_use_kerberos will be set to "true".
dnl
+dnl Sets the Automake conditional KRB5_USES_COM_ERR saying whether we use
+dnl com_err, since if we're also linking with AFS libraries, we may have to
+dnl change library ordering in that case.
+dnl
+dnl Depends on RRA_ENABLE_REDUCED_DEPENDS and RRA_SET_LDFLAGS.
+dnl
dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2005, 2006, 2007, 2008
+dnl Copyright 2005, 2006, 2007, 2008, 2009
dnl Board of Trustees, Leland Stanford Jr. University
dnl
dnl See LICENSE for licensing terms.
-dnl Set CPPFLAGS, LDFLAGS, and LIBS to values including the Kerberos v5
-dnl settings.
-AC_DEFUN([RRA_LIB_KRB5_SET],
-[CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS"
- LDFLAGS="$KRB5_LDFLAGS $LDFLAGS"
- LIBS="$KRB5_LIBS $LIBS"])
-
dnl Save the current CPPFLAGS, LDFLAGS, and LIBS settings and switch to
dnl versions that include the Kerberos v5 flags. Used as a wrapper, with
dnl RRA_LIB_KRB5_RESTORE, around tests.
@@ -44,7 +38,9 @@ AC_DEFUN([RRA_LIB_KRB5_SWITCH],
[rra_krb5_save_CPPFLAGS="$CPPFLAGS"
rra_krb5_save_LDFLAGS="$LDFLAGS"
rra_krb5_save_LIBS="$LIBS"
- RRA_LIB_KRB5_SET])
+ CPPFLAGS="$KRB5_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$KRB5_LDFLAGS $LDFLAGS"
+ LIBS="$KRB5_LIBS $LIBS"])
dnl Restore CPPFLAGS, LDFLAGS, and LIBS to their previous values (before
dnl RRA_LIB_KRB5_SWITCH was called).
@@ -53,12 +49,18 @@ AC_DEFUN([RRA_LIB_KRB5_RESTORE],
LDFLAGS="$rra_krb5_save_LDFLAGS"
LIBS="$rra_krb5_save_LIBS"])
-dnl Set KRB5_CPPFLAGS and KRB5_LDFLAGS based on rra_krb5_root.
+dnl Set KRB5_CPPFLAGS and KRB5_LDFLAGS based on rra_krb5_root,
+dnl rra_krb5_libdir, and rra_krb5_includedir.
AC_DEFUN([_RRA_LIB_KRB5_PATHS],
-[AS_IF([test x"$rra_krb5_root" != x],
- [AS_IF([test x"$rra_krb5_root" != x/usr],
- [KRB5_CPPFLAGS="-I${rra_krb5_root}/include"])
- KRB5_LDFLAGS="-L${rra_krb5_root}/lib"])])
+[AS_IF([test x"$rra_krb5_libdir" != x],
+ [KRB5_LDFLAGS="-L$rra_krb5_libdir"],
+ [AS_IF([test x"$rra_krb5_root" != x],
+ [RRA_SET_LDFLAGS([KRB5_LDFLAGS], [$rra_krb5_root])])])
+ AS_IF([test x"$rra_krb5_includedir" != x],
+ [KRB5_CPPFLAGS="-I$rra_krb5_includedir"],
+ [AS_IF([test x"$rra_krb5_root" != x],
+ [AS_IF([test x"$rra_krb5_root" != x/usr],
+ [KRB5_CPPFLAGS="-I${rra_krb5_root}/include"])])])])
dnl Does the appropriate library checks for reduced-dependency Kerberos v5
dnl linkage. The single argument, if true, says to fail if Kerberos could not
@@ -71,15 +73,16 @@ AC_DEFUN([_RRA_LIB_KRB5_REDUCED],
LIBS="$KRB5_LIBS $LIBS"
AC_CHECK_FUNCS([krb5_get_error_message],
[AC_CHECK_FUNCS([krb5_free_error_message])],
- [AC_CHECK_FUNCS([krb5_get_err_txt], ,
- [AC_CHECK_LIB([ksvc], [krb5_svc_get_msg],
- [KRB5_LIBS="$KRB5_LIBS -lksvc"
- AC_DEFINE([HAVE_KRB5_SVC_GET_MSG], [1])
- AC_CHECK_HEADERS([ibm_svc/krb5_svc.h])],
- [AC_CHECK_LIB([com_err], [com_err],
- [KRB5_LIBS="$KRB5_LIBS -lcom_err"],
- [AC_MSG_ERROR([cannot find usable com_err library])])
- AC_CHECK_HEADERS([et/com_err.h])])])])
+ [AC_CHECK_FUNCS([krb5_get_error_string], ,
+ [AC_CHECK_FUNCS([krb5_get_err_txt], ,
+ [AC_CHECK_LIB([ksvc], [krb5_svc_get_msg],
+ [KRB5_LIBS="$KRB5_LIBS -lksvc"
+ AC_DEFINE([HAVE_KRB5_SVC_GET_MSG], [1])
+ AC_CHECK_HEADERS([ibm_svc/krb5_svc.h])],
+ [AC_CHECK_LIB([com_err], [com_err],
+ [KRB5_LIBS="$KRB5_LIBS -lcom_err"],
+ [AC_MSG_ERROR([cannot find usable com_err library])])
+ AC_CHECK_HEADERS([et/com_err.h])])])])])
RRA_LIB_KRB5_RESTORE])
dnl Does the appropriate library checks for Kerberos v5 linkage when we don't
@@ -126,24 +129,26 @@ AC_DEFUN([_RRA_LIB_KRB5_MANUAL],
LIBS="$KRB5_LIBS $LIBS"
AC_CHECK_FUNCS([krb5_get_error_message],
[AC_CHECK_FUNCS([krb5_free_error_message])],
- [AC_CHECK_FUNCS([krb5_get_err_txt], ,
- [AC_CHECK_FUNCS([krb5_svc_get_msg],
- [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h])],
- [AC_CHECK_HEADERS([et/com_err.h])])])])
+ [AC_CHECK_FUNCS([krb5_get_error_string], ,
+ [AC_CHECK_FUNCS([krb5_get_err_txt], ,
+ [AC_CHECK_FUNCS([krb5_svc_get_msg],
+ [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h])],
+ [AC_CHECK_HEADERS([et/com_err.h])])])])])
RRA_LIB_KRB5_RESTORE])
dnl Sanity-check the results of krb5-config and be sure we can really link a
-dnl Kerberos program. The first option says whether to fail if Kerberos was
-dnl not found. If we shouldn't fail, clear KRB5_CPPFLAGS and KRB5_LIBS so
-dnl that we know we don't have usable flags.
+dnl Kerberos program. If that fails, clear KRB5_CPPFLAGS and KRB5_LIBS so
+dnl that we know we don't have usable flags and fall back on the manual
+dnl check.
AC_DEFUN([_RRA_LIB_KRB5_CHECK],
[RRA_LIB_KRB5_SWITCH
- AC_CHECK_FUNC([krb5_init_context], ,
- [AS_IF([test x"$1" = xtrue],
- [AC_MSG_FAILURE([krb5-config results fail for Kerberos v5])])
+ AC_CHECK_FUNC([krb5_init_context],
+ [RRA_LIB_KRB5_RESTORE],
+ [RRA_LIB_KRB5_RESTORE
KRB5_CPPFLAGS=
- KRB5_LIBS=])
- RRA_LIB_KRB5_RESTORE])
+ KRB5_LIBS=
+ _RRA_LIB_KRB5_PATHS
+ _RRA_LIB_KRB5_MANUAL([$1])])])
dnl The core of the library checking, shared between RRA_LIB_KRB5 and
dnl RRA_LIB_KRB5_OPTIONAL. The single argument, if "true", says to fail if
@@ -161,23 +166,24 @@ AC_DEFUN([_RRA_LIB_KRB5_INTERNAL],
AS_IF([test x"$KRB5_CONFIG" != x && test -x "$KRB5_CONFIG"],
[AC_CACHE_CHECK([for krb5 support in krb5-config],
[rra_cv_lib_krb5_config],
- [AS_IF(["$KRB5_CONFIG" | grep krb5 > /dev/null 2>&1],
+ [AS_IF(["$KRB5_CONFIG" 2>&1 | grep krb5 >/dev/null 2>&1],
[rra_cv_lib_krb5_config=yes],
[rra_cv_lib_krb5_config=no])])
- AS_IF([test "$rra_cv_lib_krb5_config" = yes],
- [KRB5_CPPFLAGS=`"$KRB5_CONFIG" --cflags krb5`
- KRB5_LIBS=`"$KRB5_CONFIG" --libs krb5`],
- [KRB5_CPPFLAGS=`"$KRB5_CONFIG" --cflags`
- KRB5_LIBS=`"$KRB5_CONFIG" --libs`])
+ AS_IF([test x"$rra_cv_lib_krb5_config" = xyes],
+ [KRB5_CPPFLAGS=`"$KRB5_CONFIG" --cflags krb5 2>/dev/null`
+ KRB5_LIBS=`"$KRB5_CONFIG" --libs krb5 2>/dev/null`],
+ [KRB5_CPPFLAGS=`"$KRB5_CONFIG" --cflags 2>/dev/null`
+ KRB5_LIBS=`"$KRB5_CONFIG" --libs 2>/dev/null`])
KRB5_CPPFLAGS=`echo "$KRB5_CPPFLAGS" | sed 's%-I/usr/include ?%%'`
_RRA_LIB_KRB5_CHECK([$1])
RRA_LIB_KRB5_SWITCH
AC_CHECK_FUNCS([krb5_get_error_message],
[AC_CHECK_FUNCS([krb5_free_error_message])],
- [AC_CHECK_FUNCS([krb5_get_err_txt], ,
- [AC_CHECK_FUNCS([krb5_svc_get_msg],
- [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h])],
- [AC_CHECK_HEADERS([et/com_err.h])])])])
+ [AC_CHECK_FUNCS([krb5_get_error_string], ,
+ [AC_CHECK_FUNCS([krb5_get_err_txt], ,
+ [AC_CHECK_FUNCS([krb5_svc_get_msg],
+ [AC_CHECK_HEADERS([ibm_svc/krb5_svc.h])],
+ [AC_CHECK_HEADERS([et/com_err.h])])])])])
RRA_LIB_KRB5_RESTORE],
[_RRA_LIB_KRB5_PATHS
_RRA_LIB_KRB5_MANUAL([$1])])])
@@ -192,22 +198,37 @@ AC_DEFUN([_RRA_LIB_KRB5_INTERNAL],
dnl The main macro for packages with mandatory Kerberos support.
AC_DEFUN([RRA_LIB_KRB5],
[rra_krb5_root=
+ rra_krb5_libdir=
+ rra_krb5_includedir=
KRB5_CPPFLAGS=
KRB5_LDFLAGS=
KRB5_LIBS=
AC_SUBST([KRB5_CPPFLAGS])
AC_SUBST([KRB5_LDFLAGS])
AC_SUBST([KRB5_LIBS])
+
AC_ARG_WITH([krb5],
- [AC_HELP_STRING([--with-krb5=DIR],
+ [AS_HELP_STRING([--with-krb5=DIR],
[Location of Kerberos v5 headers and libraries])],
[AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
[rra_krb5_root="$withval"])])
+ AC_ARG_WITH([krb5-include],
+ [AS_HELP_STRING([--with-krb5-include=DIR],
+ [Location of Kerberos v5 headers])],
+ [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
+ [rra_krb5_includedir="$withval"])])
+ AC_ARG_WITH([krb5-lib],
+ [AS_HELP_STRING([--with-krb5-lib=DIR],
+ [Location of Kerberos v5 libraries])],
+ [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
+ [rra_krb5_libdir="$withval"])])
_RRA_LIB_KRB5_INTERNAL([true])])
dnl The main macro for packages with optional Kerberos support.
AC_DEFUN([RRA_LIB_KRB5_OPTIONAL],
[rra_krb5_root=
+ rra_krb5_libdir=
+ rra_krb5_includedir=
rra_use_kerberos=
KRB5_CPPFLAGS=
KRB5_LDFLAGS=
@@ -215,13 +236,25 @@ AC_DEFUN([RRA_LIB_KRB5_OPTIONAL],
AC_SUBST([KRB5_CPPFLAGS])
AC_SUBST([KRB5_LDFLAGS])
AC_SUBST([KRB5_LIBS])
+
AC_ARG_WITH([krb5],
- [AC_HELP_STRING([--with-krb5@<:@=DIR@:>@],
+ [AS_HELP_STRING([--with-krb5@<:@=DIR@:>@],
[Location of Kerberos v5 headers and libraries])],
[AS_IF([test x"$withval" = xno],
[rra_use_kerberos=false],
[AS_IF([test x"$withval" != xyes], [rra_krb5_root="$withval"])
rra_use_kerberos=true])])
+ AC_ARG_WITH([krb5-include],
+ [AS_HELP_STRING([--with-krb5-include=DIR],
+ [Location of Kerberos v5 headers])],
+ [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
+ [rra_krb5_includedir="$withval"])])
+ AC_ARG_WITH([krb5-lib],
+ [AS_HELP_STRING([--with-krb5-lib=DIR],
+ [Location of Kerberos v5 libraries])],
+ [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
+ [rra_krb5_libdir="$withval"])])
+
AS_IF([test x"$rra_use_kerberos" != xfalse],
[AS_IF([test x"$rra_use_kerberos" = xtrue],
[_RRA_LIB_KRB5_INTERNAL([true])],
diff --git a/m4/lib-depends.m4 b/m4/lib-depends.m4
index 5f4c284..039e245 100644
--- a/m4/lib-depends.m4
+++ b/m4/lib-depends.m4
@@ -1,5 +1,4 @@
-dnl lib-depends.m4 -- Provides option to change library probes.
-dnl $Id$
+dnl Provides option to change library probes.
dnl
dnl This file provides RRA_ENABLE_REDUCED_DEPENDS, which adds the configure
dnl option --enable-reduced-depends to request that library probes assume
@@ -19,6 +18,6 @@ dnl See LICENSE for licensing terms.
AC_DEFUN([RRA_ENABLE_REDUCED_DEPENDS],
[rra_reduced_depends=false
AC_ARG_ENABLE([reduced-depends],
- [AC_HELP_STRING([--enable-reduced-depends],
+ [AS_HELP_STRING([--enable-reduced-depends],
[Try to minimize shared library dependencies])],
[AS_IF([test x"$enableval" = xyes], [rra_reduced_depends=true])])])
diff --git a/m4/lib-pathname.m4 b/m4/lib-pathname.m4
new file mode 100644
index 0000000..fc326a0
--- /dev/null
+++ b/m4/lib-pathname.m4
@@ -0,0 +1,55 @@
+dnl Determine the library path name.
+dnl
+dnl Red Hat systems and some other Linux systems use lib64 and lib32 rather
+dnl than just lib in some circumstances. This file provides an Autoconf
+dnl macro, RRA_SET_LDFLAGS, which given a variable, a prefix, and an optional
+dnl suffix, adds -Lprefix/lib, -Lprefix/lib32, or -Lprefix/lib64 to the
+dnl variable depending on which directories exist and the size of a long in
+dnl the compilation environment. If a suffix is given, a slash and that
+dnl suffix will be appended, to allow for adding a subdirectory of the library
+dnl directory.
+dnl
+dnl This file also provides the Autoconf macro RRA_SET_LIBDIR, which sets the
+dnl libdir variable to PREFIX/lib{,32,64} as appropriate.
+dnl
+dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Copyright 2008, 2009 Board of Trustees, Leland Stanford Jr. University
+dnl
+dnl See LICENSE for licensing terms.
+
+dnl Probe for the alternate library name that we should attempt on this
+dnl architecture, given the size of an int, and set rra_lib_arch_name to that
+dnl name. Separated out so that it can be AC_REQUIRE'd and not run multiple
+dnl times.
+dnl
+dnl There is an unfortunate abstraction violation here where we assume we know
+dnl the cache variable name used by Autoconf. Unfortunately, Autoconf doesn't
+dnl provide any other way of getting at that information in shell that I can
+dnl see.
+AC_DEFUN([_RRA_LIB_ARCH_NAME],
+[rra_lib_arch_name=lib
+ AC_CHECK_SIZEOF([long])
+ AS_IF([test "$ac_cv_sizeof_long" -eq 4 && test -d /usr/lib32],
+ [rra_lib_arch_name=lib32],
+ [AS_IF([test "$ac_cv_sizeof_long" -eq 8 && test -d /usr/lib64],
+ [rra_lib_arch_name=lib64])])])
+
+dnl Set VARIABLE to -LPREFIX/lib{,32,64} or -LPREFIX/lib{,32,64}/SUFFIX as
+dnl appropriate.
+AC_DEFUN([RRA_SET_LDFLAGS],
+[AC_REQUIRE([_RRA_LIB_ARCH_NAME])
+ AS_IF([test -d "$2/$rra_lib_arch_name"],
+ [AS_IF([test x"$3" = x],
+ [$1="[$]$1 -L$2/${rra_lib_arch_name}"],
+ [$1="[$]$1 -L$2/${rra_lib_arch_name}/$3"])],
+ [AS_IF([test x"$3" = x],
+ [$1="[$]$1 -L$2/lib"],
+ [$1="[$]$1 -L$2/lib/$3"])])
+ $1=`echo "[$]$1" | sed -e 's/^ *//'`])
+
+dnl Set libdir to PREFIX/lib{,32,64} as appropriate.
+AC_DEFUN([RRA_SET_LIBDIR],
+[AC_REQUIRE([_RRA_LIB_ARCH_NAME])
+ AS_IF([test -d "$1/$rra_lib_arch_name"],
+ [libdir="$1/${rra_lib_arch_name}"],
+ [libdir="$1/lib"])])
diff --git a/m4/remctl.m4 b/m4/remctl.m4
index 5cebc68..8ee3c16 100644
--- a/m4/remctl.m4
+++ b/m4/remctl.m4
@@ -1,28 +1,25 @@
-dnl remctl.m4 -- Find the compiler and linker flags for remctl.
-dnl $Id$
+dnl Find the compiler and linker flags for remctl.
dnl
-dnl This file provides RRA_LIB_REMCTL, which finds the compiler and linker
-dnl flags for linking with remctl libraries and sets the substitution
-dnl variables REMCTL_CPPFLAGS, REMCTL_LDFLAGS, and REMCTL_LIBS. Also provides
-dnl RRA_LIB_REMCTL_SET to set CPPFLAGS, LDFLAGS, and LIBS to include the
-dnl remctl libraries; RRA_LIB_REMCTL_SWITCH to do the same but save the
-dnl current values first; and RRA_LIB_REMCTL_RESTORE to restore those settings
-dnl to before the last RRA_LIB_REMCTL_SWITCH.
+dnl Finds the compiler and linker flags for linking with remctl libraries.
+dnl Provides the --with-remctl, --with-remctl-include, and --with-remctl-lib
+dnl configure options to specify non-standard paths to the remctl headers and
+dnl libraries.
dnl
-dnl This macro depends on RRA_ENABLE_REDUCED_DEPENDS and RRA_LIB_GSSAPI.
+dnl Provides the macro RRA_LIB_REMCTL and sets the substitution variables
+dnl REMCTL_CPPFLAGS, REMCTL_LDFLAGS, and REMCTL_LIBS. Also provides
+dnl RRA_LIB_REMCTL_SWITCH to set CPPFLAGS, LDFLAGS, and LIBS to include the
+dnl remctl libraries, saving the current values first, and
+dnl RRA_LIB_REMCTL_RESTORE to restore those settings to before the last
+dnl RRA_LIB_REMCTL_SWITCH.
+dnl
+dnl Depends on RRA_ENABLE_REDUCED_DEPENDS, RRA_SET_LDFLAGS, and
+dnl RRA_LIB_GSSAPI.
dnl
dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+dnl Copyright 2008, 2009 Board of Trustees, Leland Stanford Jr. University
dnl
dnl See LICENSE for licensing terms.
-dnl Set CPPFLAGS, LDFLAGS, and LIBS to values including the Kerberos v5
-dnl settings.
-AC_DEFUN([RRA_LIB_REMCTL_SET],
-[CPPFLAGS="$REMCTL_CPPFLAGS $CPPFLAGS"
- LDFLAGS="$REMCTL_LDFLAGS $LDFLAGS"
- LIBS="$REMCTL_LIBS $LIBS"])
-
dnl Save the current CPPFLAGS, LDFLAGS, and LIBS settings and switch to
dnl versions that include the Kerberos v5 flags. Used as a wrapper, with
dnl RRA_LIB_REMCTL_RESTORE, around tests.
@@ -30,7 +27,9 @@ AC_DEFUN([RRA_LIB_REMCTL_SWITCH],
[rra_remctl_save_CPPFLAGS="$CPPFLAGS"
rra_remctl_save_LDFLAGS="$LDFLAGS"
rra_remctl_save_LIBS="$LIBS"
- RRA_LIB_REMCTL_SET])
+ CPPFLAGS="$REMCTL_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$REMCTL_LDFLAGS $LDFLAGS"
+ LIBS="$REMCTL_LIBS $LIBS"])
dnl Restore CPPFLAGS, LDFLAGS, and LIBS to their previous values (before
dnl RRA_LIB_REMCTL_SWITCH was called).
@@ -39,32 +38,61 @@ AC_DEFUN([RRA_LIB_REMCTL_RESTORE],
LDFLAGS="$rra_remctl_save_LDFLAGS"
LIBS="$rra_remctl_save_LIBS"])
-dnl Set REMCTL_CPPFLAGS and REMCTL_LDFLAGS based on rra_remctl_root.
+dnl Set REMCTL_CPPFLAGS and REMCTL_LDFLAGS based on rra_remctl_root,
+dnl rra_remctl_libdir, and rra_remctl_includedir.
AC_DEFUN([_RRA_LIB_REMCTL_PATHS],
-[AS_IF([test x"$rra_remctl_root" != x],
- [AS_IF([test x"$rra_remctl_root" != x/usr],
- [REMCTL_CPPFLAGS="-I${rra_remctl_root}/include"])
- REMCTL_LDFLAGS="-L${rra_remctl_root}/lib"])])
+[AS_IF([test x"$rra_remctl_libdir" != x],
+ [REMCTL_LDFLAGS="-L$rra_remctl_libdir"],
+ [AS_IF([test x"$rra_remctl_root" != x],
+ [RRA_SET_LDFLAGS([REMCTL_LDFLAGS], [$rra_remctl_root])])])
+ AS_IF([test x"$rra_remctl_includedir" != x],
+ [REMCTL_CPPFLAGS="-I$rra_remctl_includedir"],
+ [AS_IF([test x"$rra_remctl_root" != x],
+ [AS_IF([test x"$rra_remctl_root" != x/usr],
+ [REMCTL_CPPFLAGS="-I${rra_remctl_root}/include"])])])])
+
+dnl Sanity-check the results of the remctl library search to be sure we can
+dnl really link a remctl program.
+AC_DEFUN([_RRA_LIB_REMCTL_CHECK],
+[RRA_LIB_REMCTL_SWITCH
+ AC_CHECK_FUNC([remctl_open], ,
+ [AC_MSG_FAILURE([unable to link with remctl library])])
+ RRA_LIB_REMCTL_RESTORE])
dnl The main macro.
AC_DEFUN([RRA_LIB_REMCTL],
[AC_REQUIRE([RRA_ENABLE_REDUCED_DEPENDS])
rra_remctl_root=
+ rra_remctl_libdir=
+ rra_remctl_includedir=
REMCTL_CPPFLAGS=
REMCTL_LDFLAGS=
REMCTL_LIBS=
AC_SUBST([REMCTL_CPPFLAGS])
AC_SUBST([REMCTL_LDFLAGS])
AC_SUBST([REMCTL_LIBS])
+
AC_ARG_WITH([remctl],
- [AC_HELP_STRING([--with-remctl=DIR],
+ [AS_HELP_STRING([--with-remctl=DIR],
[Location of remctl headers and libraries])],
[AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
[rra_remctl_root="$withval"])])
+ AC_ARG_WITH([remctl-include],
+ [AS_HELP_STRING([--with-remctl-include=DIR],
+ [Location of remctl headers])],
+ [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
+ [rra_remctl_includedir="$withval"])])
+ AC_ARG_WITH([remctl-lib],
+ [AS_HELP_STRING([--with-remctl-lib=DIR],
+ [Location of remctl libraries])],
+ [AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
+ [rra_remctl_libdir="$withval"])])
+
_RRA_LIB_REMCTL_PATHS
AS_IF([test x"$rra_reduced_depends" = xtrue],
[REMCTL_LIBS="-lremctl"],
[RRA_LIB_GSSAPI
REMCTL_CPPFLAGS="$REMCTL_CPPFLAGS $GSSAPI_CPPFLAGS"
REMCTL_LDFLAGS="$REMCTL_LDFLAGS $GSSAPI_LDFLAGS"
- REMCTL_LIBS="-lremctl $GSSAPI_LIBS"])])
+ REMCTL_LIBS="-lremctl $GSSAPI_LIBS"])
+ _RRA_LIB_REMCTL_CHECK])
diff --git a/m4/snprintf.m4 b/m4/snprintf.m4
index 8ab3689..d933f55 100644
--- a/m4/snprintf.m4
+++ b/m4/snprintf.m4
@@ -1,5 +1,4 @@
-dnl snprintf.m4 -- Test for a working C99 snprintf.
-dnl $Id$
+dnl Test for a working C99 snprintf.
dnl
dnl Check for a working snprintf. Some systems have an snprintf that doesn't
dnl nul-terminate if the buffer isn't large enough. Others return -1 if the
@@ -11,12 +10,14 @@ dnl Provides RRA_FUNC_SNPRINTF, which adds snprintf.o to LIBOBJS unless a
dnl fully working snprintf is found.
dnl
dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2006, 2008 Board of Trustees, Leland Stanford Jr. University
+dnl Copyright 2006, 2008, 2009
+dnl Board of Trustees, Leland Stanford Jr. University
+dnl
dnl See LICENSE for licensing terms.
dnl Source used by RRA_FUNC_SNPRINTF.
-define([_RRA_FUNC_SNPRINTF_SOURCE],
-[[#include <stdio.h>
+AC_DEFUN([_RRA_FUNC_SNPRINTF_SOURCE], [[
+#include <stdio.h>
#include <stdarg.h>
char buf[2];
@@ -38,16 +39,17 @@ main()
{
return ((test("%s", "abcd") == 4 && buf[0] == 'a' && buf[1] == '\0'
&& snprintf(NULL, 0, "%s", "abcd") == 4) ? 0 : 1);
-}]])
+}
+]])
dnl The user-callable test.
AC_DEFUN([RRA_FUNC_SNPRINTF],
[AC_CACHE_CHECK([for working snprintf], [rra_cv_func_snprintf_works],
- [AC_TRY_RUN(_RRA_FUNC_SNPRINTF_SOURCE(),
+ [AC_RUN_IFELSE([AC_LANG_SOURCE([_RRA_FUNC_SNPRINTF_SOURCE])],
[rra_cv_func_snprintf_works=yes],
[rra_cv_func_snprintf_works=no],
[rra_cv_func_snprintf_works=no])])
-AS_IF([test "$rra_cv_func_snprintf_works" = yes],
+ AS_IF([test x"$rra_cv_func_snprintf_works" = xyes],
[AC_DEFINE([HAVE_SNPRINTF], 1,
[Define if your system has a working snprintf function.])],
[AC_LIBOBJ([snprintf])])])
diff --git a/m4/vamacros.m4 b/m4/vamacros.m4
index 8946d8b..855bb40 100644
--- a/m4/vamacros.m4
+++ b/m4/vamacros.m4
@@ -1,5 +1,4 @@
-dnl vamacros.m4 -- Check for support for variadic macros.
-dnl $Id$
+dnl Check for support for variadic macros.
dnl
dnl This file defines two macros for probing for compiler support for variadic
dnl macros. Provided are RRA_C_C99_VAMACROS, which checks for support for the
@@ -15,30 +14,49 @@ dnl
dnl They set HAVE_C99_VAMACROS or HAVE_GNU_VAMACROS as appropriate.
dnl
dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2006, 2008 Board of Trustees, Leland Stanford Jr. University
+dnl Copyright 2006, 2008, 2009
+dnl Board of Trustees, Leland Stanford Jr. University
dnl
dnl See LICENSE for licensing terms.
+AC_DEFUN([_RRA_C_C99_VAMACROS_SOURCE], [[
+#include <stdio.h>
+#define error(...) fprintf(stderr, __VA_ARGS__)
+
+int
+main(void) {
+ error("foo");
+ error("foo %d", 0);
+ return 0;
+}
+]])
+
AC_DEFUN([RRA_C_C99_VAMACROS],
[AC_CACHE_CHECK([for C99 variadic macros], [rra_cv_c_c99_vamacros],
-[AC_TRY_COMPILE(
-[#include <stdio.h>
-#define error(...) fprintf(stderr, __VA_ARGS__)],
- [error("foo"); error("foo %d", 0); return 0;],
- [rra_cv_c_c99_vamacros=yes],
- [rra_cv_c_c99_vamacros=no])])
-AS_IF([test $rra_cv_c_c99_vamacros = yes],
+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_RRA_C_C99_VAMACROS_SOURCE])],
+ [rra_cv_c_c99_vamacros=yes],
+ [rra_cv_c_c99_vamacros=no])])
+ AS_IF([test x"$rra_cv_c_c99_vamacros" = xyes],
[AC_DEFINE([HAVE_C99_VAMACROS], 1,
- [Define if the compiler supports C99 variadic macros.])])])
+ [Define if the compiler supports C99 variadic macros.])])])
+
+AC_DEFUN([_RRA_C_GNU_VAMACROS_SOURCE], [[
+#include <stdio.h>
+#define error(args...) fprintf(stderr, args)
+
+int
+main(void) {
+ error("foo");
+ error("foo %d", 0);
+ return 0;
+}
+]])
AC_DEFUN([RRA_C_GNU_VAMACROS],
[AC_CACHE_CHECK([for GNU-style variadic macros], [rra_cv_c_gnu_vamacros],
-[AC_TRY_COMPILE(
-[#include <stdio.h>
-#define error(args...) fprintf(stderr, args)],
- [error("foo"); error("foo %d", 0); return 0;],
- [rra_cv_c_gnu_vamacros=yes],
- [rra_cv_c_gnu_vamacros=no])])
-AS_IF([test $rra_cv_c_gnu_vamacros = yes],
+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_RRA_C_GNU_VAMACROS_SOURCE])],
+ [rra_cv_c_gnu_vamacros=yes],
+ [rra_cv_c_gnu_vamacros=no])])
+ AS_IF([test x"$rra_cv_c_gnu_vamacros" = xyes],
[AC_DEFINE([HAVE_GNU_VAMACROS], 1,
- [Define if the compiler supports GNU-style variadic macros.])])])
+ [Define if the compiler supports GNU-style variadic macros.])])])
diff --git a/perl/Makefile.PL.in b/perl/Makefile.PL.in
index 1ba6004..5804d9b 100644
--- a/perl/Makefile.PL.in
+++ b/perl/Makefile.PL.in
@@ -1,5 +1,4 @@
# Makefile.PL for the Wallet Perl library. -*- perl -*-
-# $Id$
use ExtUtils::MakeMaker;
diff --git a/perl/Wallet/ACL.pm b/perl/Wallet/ACL.pm
index b96d2ac..76e7354 100644
--- a/perl/Wallet/ACL.pm
+++ b/perl/Wallet/ACL.pm
@@ -1,8 +1,7 @@
# Wallet::ACL -- Implementation of ACLs in the wallet system.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -22,7 +21,7 @@ use POSIX qw(strftime);
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.05';
+$VERSION = '0.06';
##############################################################################
# Constructors
@@ -428,6 +427,9 @@ __END__
Wallet::ACL - Implementation of ACLs in the wallet system
+=for stopwords
+ACL DBH metadata HOSTNAME DATETIME timestamp Allbery
+
=head1 SYNOPSIS
my $acl = Wallet::ACL->create ('group:sysadmin');
@@ -446,22 +448,22 @@ Wallet::ACL - Implementation of ACLs in the wallet system
=head1 DESCRIPTION
-Wallet::ACL implements the ACL system for the wallet: the methods to create,
-find, rename, and destroy ACLs; the methods to add and remove entries from
-an ACL; and the methods to list the contents of an ACL and check a principal
-against it.
+Wallet::ACL implements the ACL system for the wallet: the methods to
+create, find, rename, and destroy ACLs; the methods to add and remove
+entries from an ACL; and the methods to list the contents of an ACL and
+check a principal against it.
An ACL is a list of zero or more ACL entries, each of which consists of a
-scheme and an identifier. Each scheme is associated with a verifier module
-that checks Kerberos principals against identifiers for that scheme and
-returns whether the principal should be permitted access by that identifier.
-The interpretation of the identifier is entirely left to the scheme. This
-module maintains the ACLs and dispatches check operations to the appropriate
-verifier module.
-
-Each ACL is identified by a human-readable name and a persistant unique
-numeric identifier. The numeric identifier (ID) should be used to refer to
-the ACL so that it can be renamed as needed without breaking external
+scheme and an identifier. Each scheme is associated with a verifier
+module that checks Kerberos principals against identifiers for that scheme
+and returns whether the principal should be permitted access by that
+identifier. The interpretation of the identifier is entirely left to the
+scheme. This module maintains the ACLs and dispatches check operations to
+the appropriate verifier module.
+
+Each ACL is identified by a human-readable name and a persistent unique
+numeric identifier. The numeric identifier (ID) should be used to refer
+to the ACL so that it can be renamed as needed without breaking external
references.
=head1 CLASS METHODS
@@ -482,8 +484,8 @@ finding an existing one, creates a new ACL record in the database with the
given NAME. NAME must not be all-numeric, since that would conflict with
the automatically assigned IDs. Returns the new object on success and
throws an exception on failure. PRINCIPAL, HOSTNAME, and DATETIME are
-stored as history information. PRINCIPAL should be the user who is creating
-the ACL. If DATETIME isn't given, the current time is used.
+stored as history information. PRINCIPAL should be the user who is
+creating the ACL. If DATETIME isn't given, the current time is used.
=back
@@ -493,42 +495,43 @@ the ACL. If DATETIME isn't given, the current time is used.
=item add(SCHEME, INSTANCE, PRINCIPAL, HOSTNAME [, DATETIME])
-Add the given ACL entry (given by SCHEME and INSTANCE) to this ACL. Returns
-true on success and false on failure. On failure, the caller should call
-error() to get the error message. PRINCIPAL, HOSTNAME, and DATETIME are
-stored as history information. PRINCIPAL should be the user who is adding
-the ACL entry. If DATETIME isn't given, the current time is used.
+Add the given ACL entry (given by SCHEME and INSTANCE) to this ACL.
+Returns true on success and false on failure. On failure, the caller
+should call error() to get the error message. PRINCIPAL, HOSTNAME, and
+DATETIME are stored as history information. PRINCIPAL should be the user
+who is adding the ACL entry. If DATETIME isn't given, the current time is
+used.
=item check(PRINCIPAL)
Checks whether the given PRINCIPAL should be allowed access given ACL.
Returns 1 if access was granted, 0 if access is declined, and undef on
-error. On error, the caller should call error() to get the error text. Any
-errors found by the individual ACL verifiers can be retrieved by calling
-check_errors(). Errors from individual ACL verifiers will not result in an
-error return from check(); instead, the check will continue with the next
-entry in the ACL.
+error. On error, the caller should call error() to get the error text.
+Any errors found by the individual ACL verifiers can be retrieved by
+calling check_errors(). Errors from individual ACL verifiers will not
+result in an error return from check(); instead, the check will continue
+with the next entry in the ACL.
check() returns success as soon as an entry in the ACL grants access to
PRINCIPAL. There is no provision for negative ACLs or exceptions.
=item check_errors()
-Return (as a list in array context and a string with newlines between errors
-and at the end of the last error in scalar context) the errors, if any,
-returned by ACL verifiers for the last check operation. If there were no
-errors from the last check() operation, returns the empty list in array
-context and undef in scalar context.
+Return (as a list in array context and a string with newlines between
+errors and at the end of the last error in scalar context) the errors, if
+any, returned by ACL verifiers for the last check operation. If there
+were no errors from the last check() operation, returns the empty list in
+array context and undef in scalar context.
=item destroy(PRINCIPAL, HOSTNAME [, DATETIME])
Destroys this ACL from the database. Note that this will fail due to
integrity constraint errors if the ACL is still referenced by any object;
-the ACL must be removed from all objects first. Returns true on success and
-false on failure. On failure, the caller should call error() to get the
-error message. PRINCIPAL, HOSTNAME, and DATETIME are stored as history
-information. PRINCIPAL should be the user who is destroying the ACL. If
-DATETIME isn't given, the current time is used.
+the ACL must be removed from all objects first. Returns true on success
+and false on failure. On failure, the caller should call error() to get
+the error message. PRINCIPAL, HOSTNAME, and DATETIME are stored as
+history information. PRINCIPAL should be the user who is destroying the
+ACL. If DATETIME isn't given, the current time is used.
=item error()
@@ -543,7 +546,8 @@ the ACL (not including changes to the name of the ACL) will be represented
by two lines. The first line will have a timestamp of the change followed
by a description of the change, and the second line will give the user who
made the change and the host from which the change was made. On failure,
-returns undef, and the caller should call error() to get the error message.
+returns undef, and the caller should call error() to get the error
+message.
=item id()
@@ -570,28 +574,29 @@ Returns the human-readable name of this ACL.
=item remove(SCHEME, INSTANCE, PRINCIPAL, HOSTNAME [, DATETIME])
Remove the given ACL line (given by SCHEME and INSTANCE) from this ACL.
-Returns true on success and false on failure. On failure, the caller should
-call error() to get the error message. PRINCIPAL, HOSTNAME, and DATETIME
-are stored as history information. PRINCIPAL should be the user who is
-removing the ACL entry. If DATETIME isn't given, the current time is used.
+Returns true on success and false on failure. On failure, the caller
+should call error() to get the error message. PRINCIPAL, HOSTNAME, and
+DATETIME are stored as history information. PRINCIPAL should be the user
+who is removing the ACL entry. If DATETIME isn't given, the current time
+is used.
=item rename(NAME)
Rename this ACL. This changes the name used for human convenience but not
the system-generated ACL ID that is used to reference this ACL. The new
NAME must not be all-numeric, since that would conflict with
-system-generated ACL IDs. Returns true on success and false on failure. On
-failure, the caller should call error() to get the error message.
+system-generated ACL IDs. Returns true on success and false on failure.
+On failure, the caller should call error() to get the error message.
Note that rename() operations are not logged in the ACL history.
=item show()
-Returns a human-readable description of this ACL, including its membership.
-This method should only be used for display of the ACL to humans. Use the
-list(), name(), and id() methods instead to get ACL information for use in
-other code. On failure, returns undef, and the caller should call error()
-to get the error message.
+Returns a human-readable description of this ACL, including its
+membership. This method should only be used for display of the ACL to
+humans. Use the list(), name(), and id() methods instead to get ACL
+information for use in other code. On failure, returns undef, and the
+caller should call error() to get the error message.
=back
@@ -599,8 +604,8 @@ to get the error message.
Wallet::ACL::Base(3), wallet-backend(8)
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/ACL/Base.pm b/perl/Wallet/ACL/Base.pm
index 87df824..9a8a3cb 100644
--- a/perl/Wallet/ACL/Base.pm
+++ b/perl/Wallet/ACL/Base.pm
@@ -1,8 +1,7 @@
# Wallet::ACL::Base -- Parent class for wallet ACL verifiers.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -19,7 +18,7 @@ use vars qw($VERSION);
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.01';
+$VERSION = '0.02';
##############################################################################
# Interface
@@ -60,6 +59,9 @@ __END__
# Documentation
##############################################################################
+=for stopwords
+ACL Allbery
+
=head1 NAME
Wallet::ACL::Base - Generic parent class for wallet ACL verifiers
@@ -75,9 +77,9 @@ Wallet::ACL::Base - Generic parent class for wallet ACL verifiers
=head1 DESCRIPTION
-Wallet::ACL::Base is the generic parent class for wallet ACL verifiers. It
-provides default functions and behavior and all ACL verifiers should inherit
-from it. It is not used directly.
+Wallet::ACL::Base is the generic parent class for wallet ACL verifiers.
+It provides default functions and behavior and all ACL verifiers should
+inherit from it. It is not used directly.
=head1 METHODS
@@ -85,8 +87,8 @@ from it. It is not used directly.
=item new()
-Creates a new ACL verifier. The generic function provided here just creates
-and blesses an object.
+Creates a new ACL verifier. The generic function provided here just
+creates and blesses an object.
=item check(PRINCIPAL, ACL)
@@ -100,11 +102,11 @@ have failed. Callers should call this function to get the error message
after an undef return from any other instance method.
For the convenience of child classes, this method can also be called with
-one or more error strings. If so, those strings are concatenated together,
-trailing newlines are removed, any text of the form S<C< at \S+ line
-\d+\.?>> at the end of the message is stripped off, and the result is stored
-as the error. Only child classes should call this method with an error
-string.
+one or more error strings. If so, those strings are concatenated
+together, trailing newlines are removed, any text of the form S<C< at \S+
+line \d+\.?>> at the end of the message is stripped off, and the result is
+stored as the error. Only child classes should call this method with an
+error string.
=back
@@ -112,8 +114,8 @@ string.
Wallet::ACL(3), wallet-backend(8)
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/ACL/Krb5.pm b/perl/Wallet/ACL/Krb5.pm
index f94475f..496fcf0 100644
--- a/perl/Wallet/ACL/Krb5.pm
+++ b/perl/Wallet/ACL/Krb5.pm
@@ -1,8 +1,7 @@
# Wallet::ACL::Krb5 -- Wallet Kerberos v5 principal ACL verifier.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -23,7 +22,7 @@ use Wallet::ACL::Base;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.01';
+$VERSION = '0.02';
##############################################################################
# Interface
@@ -51,6 +50,9 @@ __END__
# Documentation
##############################################################################
+=for stopwords
+ACL krb5 Allbery
+
=head1 NAME
Wallet::ACL::Krb5 - Simple wallet ACL verifier for Kerberos principals
@@ -70,7 +72,7 @@ Wallet::ACL::Krb5 - Simple wallet ACL verifier for Kerberos principals
=head1 DESCRIPTION
Wallet::ACL::Krb5 is the simplest wallet ACL verifier, used to verify ACL
-lines of type krb5. The value of such an ACL is a simple Kerberos
+lines of type C<krb5>. The value of such an ACL is a simple Kerberos
principal in its text display form, and the ACL grants access to a given
principal if and only if the principal exactly matches the ACL.
@@ -112,8 +114,8 @@ The PRINCIPAL parameter to check() was undefined or the empty string.
Wallet::ACL(3), Wallet::ACL::Base(3), wallet-backend(8)
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/ACL/NetDB.pm b/perl/Wallet/ACL/NetDB.pm
index cc7121b..2096ba8 100644
--- a/perl/Wallet/ACL/NetDB.pm
+++ b/perl/Wallet/ACL/NetDB.pm
@@ -1,8 +1,7 @@
# Wallet::ACL::NetDB -- Wallet NetDB role ACL verifier.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -24,7 +23,7 @@ use Wallet::Config;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.03';
+$VERSION = '0.04';
##############################################################################
# Interface
@@ -136,6 +135,9 @@ __END__
# Documentation
##############################################################################
+=for stopwords
+ACL NetDB remctl DNS DHCP Allbery netdb
+
=head1 NAME
Wallet::ACL::NetDB - Wallet ACL verifier for NetDB roles
@@ -155,9 +157,10 @@ Wallet::ACL::NetDB - Wallet ACL verifier for NetDB roles
=head1 DESCRIPTION
Wallet::ACL::NetDB checks a principal against the NetDB roles for a given
-host. It is used to verify ACL lines of type netdb. The value of such an
-ACL is a node, and the ACL grants access to a given principal if and only
-if that principal has one of the roles user, admin, or team for that node.
+host. It is used to verify ACL lines of type C<netdb>. The value of such
+an ACL is a node, and the ACL grants access to a given principal if and
+only if that principal has one of the roles user, admin, or team for that
+node.
To use this object, several configuration parameters must be set. See
Wallet::Config(3) for details on those configuration parameters and
@@ -228,7 +231,7 @@ error message or otherwise returned failure.
The ACL parameter to check() was malformed. Currently, this error is only
given if ACL is undefined or the empty string.
-=item malformed NetDBL remctl token: %s
+=item malformed NetDB remctl token: %s
The Net::Remctl Perl library returned a malformed token. This should
never happen and indicates a bug in Net::Remctl.
@@ -249,12 +252,12 @@ grant access is not currently configurable.
Net::Remctl(3), Wallet::ACL(3), Wallet::ACL::Base(3), Wallet::Config(3),
wallet-backend(8)
-NetDB is a free software system for managing DNS, DHCP, and related machine
-information for large organizations. For more information on NetDB, see
-L<http://www.stanford.edu/group/networking/netdb/>.
+NetDB is a free software system for managing DNS, DHCP, and related
+machine information for large organizations. For more information on
+NetDB, see L<http://www.stanford.edu/group/networking/netdb/>.
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/ACL/NetDB/Root.pm b/perl/Wallet/ACL/NetDB/Root.pm
index 8c2c6b2..3aeebda 100644
--- a/perl/Wallet/ACL/NetDB/Root.pm
+++ b/perl/Wallet/ACL/NetDB/Root.pm
@@ -1,8 +1,7 @@
# Wallet::ACL::NetDB::Root -- Wallet NetDB role ACL verifier (root instances).
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -24,7 +23,7 @@ use Wallet::Config;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.01';
+$VERSION = '0.02';
##############################################################################
# Interface
@@ -49,6 +48,9 @@ sub check {
# Documentation
##############################################################################
+=for stopwords
+ACL NetDB DNS DHCP Allbery
+
=head1 NAME
Wallet::ACL::NetDB::Root - Wallet ACL verifier for NetDB roles (root instances)
@@ -67,13 +69,14 @@ Wallet::ACL::NetDB::Root - Wallet ACL verifier for NetDB roles (root instances)
=head1 DESCRIPTION
-Wallet::ACL::NetDB::Root works identically to Wallet::ACL::NetDB except that
-it requires the principal to be a root instance (in other words, to be in
-the form <principal>/root@<realm>) and strips the C</root> portion from the
-principal before checking against NetDB roles. As with the base NetDB ACL
-verifier, the value of a netdb-root ACL is a node, and the ACL grants access
-to a given principal if and only if the that principal (with C</root>
-stripped) has one of the roles user, admin, or team for that node.
+Wallet::ACL::NetDB::Root works identically to Wallet::ACL::NetDB except
+that it requires the principal to be a root instance (in other words, to
+be in the form <principal>/root@<realm>) and strips the C</root> portion
+from the principal before checking against NetDB roles. As with the base
+NetDB ACL verifier, the value of a C<netdb-root> ACL is a node, and the
+ACL grants access to a given principal if and only if the that principal
+(with C</root> stripped) has one of the roles user, admin, or team for
+that node.
To use this object, the same configuration parameters must be set as for
Wallet::ACL::NetDB. See Wallet::Config(3) for details on those
@@ -86,11 +89,11 @@ configuration.
=item check(PRINCIPAL, ACL)
-Returns true if PRINCIPAL is granted access according to ACL, false if not,
-and undef on an error (see L<"DIAGNOSTICS"> below). ACL is a node, and
-PRINCIPAL will be granted access if it has an instance of C<root> and if
-(with C</root> stripped off and the realm stripped off if configured) has
-the user, admin, or team role for that node.
+Returns true if PRINCIPAL is granted access according to ACL, false if
+not, and undef on an error (see L<"DIAGNOSTICS"> below). ACL is a node,
+and PRINCIPAL will be granted access if it has an instance of C<root> and
+if (with C</root> stripped off and the realm stripped off if configured)
+has the user, admin, or team role for that node.
=back
@@ -107,15 +110,15 @@ grant access is not currently configurable.
=head1 SEE ALSO
-Net::Remctl(3), Wallet::ACL(3), Wallet::ACL::Base(3), Wallet::ACL::NetDB(3),
-Wallet::Config(3), wallet-backend(8)
+Net::Remctl(3), Wallet::ACL(3), Wallet::ACL::Base(3),
+Wallet::ACL::NetDB(3), Wallet::Config(3), wallet-backend(8)
-NetDB is a free software system for managing DNS, DHCP, and related machine
-information for large organizations. For more information on NetDB, see
-L<http://www.stanford.edu/group/networking/netdb/>.
+NetDB is a free software system for managing DNS, DHCP, and related
+machine information for large organizations. For more information on
+NetDB, see L<http://www.stanford.edu/group/networking/netdb/>.
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/Admin.pm b/perl/Wallet/Admin.pm
index 37d538e..e835713 100644
--- a/perl/Wallet/Admin.pm
+++ b/perl/Wallet/Admin.pm
@@ -1,8 +1,7 @@
# Wallet::Admin -- Wallet system administrative interface.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -23,7 +22,7 @@ use Wallet::Schema;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.02';
+$VERSION = '0.05';
##############################################################################
# Constructor, destructor, and accessors
@@ -112,67 +111,6 @@ sub destroy {
}
##############################################################################
-# Reporting
-##############################################################################
-
-# Returns a list of all objects stored in the wallet database in the form of
-# type and name pairs. On error and for an empty database, the empty list
-# will be returned. To distinguish between an empty list and an error, call
-# error(), which will return undef if there was no error.
-sub list_objects {
- my ($self) = @_;
- undef $self->{error};
- my @objects;
- eval {
- my $sql = 'select ob_type, ob_name from objects order by ob_type,
- ob_name';
- my $sth = $self->{dbh}->prepare ($sql);
- $sth->execute;
- my $object;
- while (defined ($object = $sth->fetchrow_arrayref)) {
- push (@objects, [ @$object ]);
- }
- $self->{dbh}->commit;
- };
- if ($@) {
- $self->error ("cannot list objects: $@");
- $self->{dbh}->rollback;
- return;
- } else {
- return @objects;
- }
-}
-
-# Returns a list of all ACLs stored in the wallet database as a list of pairs
-# of ACL IDs and ACL names. On error and for an empty database, the empty
-# list will be returned; however, this is unlikely since any valid database
-# will have at least an ADMIN ACL. Still, to distinguish between an empty
-# list and an error, call error(), which will return undef if there was no
-# error.
-sub list_acls {
- my ($self) = @_;
- undef $self->{error};
- my @acls;
- eval {
- my $sql = 'select ac_id, ac_name from acls order by ac_id';
- my $sth = $self->{dbh}->prepare ($sql);
- $sth->execute;
- my $object;
- while (defined ($object = $sth->fetchrow_arrayref)) {
- push (@acls, [ @$object ]);
- }
- $self->{dbh}->commit;
- };
- if ($@) {
- $self->error ("cannot list ACLs: $@");
- $self->{dbh}->rollback;
- return;
- } else {
- return @acls;
- }
-}
-
-##############################################################################
# Object registration
##############################################################################
@@ -225,6 +163,9 @@ __DATA__
Wallet::Admin - Wallet system administrative interface
+=for stopwords
+ACL hostname Allbery
+
=head1 SYNOPSIS
use Wallet::Admin;
@@ -241,9 +182,9 @@ thin wrapper around this object that provides a command-line interface to
its actions.
To use this object, several configuration variables must be set (at least
-the database configuration). For information on those variables and how to
-set them, see Wallet::Config(3). For more information on the normal user
-interface to the wallet server, see Wallet::Server(3).
+the database configuration). For information on those variables and how
+to set them, see Wallet::Config(3). For more information on the normal
+user interface to the wallet server, see Wallet::Server(3).
=head1 CLASS METHODS
@@ -287,34 +228,6 @@ initialize() uses C<localhost> as the hostname and PRINCIPAL as the user
when logging the history of the ADMIN ACL creation and for any subsequent
actions on the object it returns.
-=item list_acls()
-
-Returns a list of all ACLs in the database. The return value is a list of
-references to pairs of ACL ID and name. For example, if there are two
-ACLs in the database, one with name "ADMIN" and ID 1 and one with name
-"group/admins" and ID 3, list_acls() would return:
-
- ([ 1, 'ADMIN' ], [ 3, 'group/admins' ])
-
-Returns the empty list on failure. Any valid wallet database should have
-at least one ACL, but an error can be distinguished from the odd case of a
-database with no ACLs by calling error(). error() is guaranteed to return
-the error message if there was an error and undef if there was no error.
-
-=item list_objects()
-
-Returns a list of all objects in the database. The return value is a list
-of references to pairs of type and name. For example, if two objects
-existed in the database, both of type "keytab" and with values
-"host/example.com" and "foo", list_objects() would return:
-
- ([ 'keytab', 'host/example.com' ], [ 'keytab', 'foo' ])
-
-Returns the empty list on failure. To distinguish between this and a
-database containing no objects, the caller should call error(). error()
-is guaranteed to return the error message if there was an error and undef
-if there was no error.
-
=item register_object (TYPE, CLASS)
Register in the database a mapping from the object type TYPE to the class
@@ -342,8 +255,8 @@ Returns true on success and false on failure.
wallet-admin(8)
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/Config.pm b/perl/Wallet/Config.pm
index 6c72781..396bf7d 100644
--- a/perl/Wallet/Config.pm
+++ b/perl/Wallet/Config.pm
@@ -1,8 +1,7 @@
# Wallet::Config -- Configuration handling for the wallet server.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -15,7 +14,7 @@ use vars qw($PATH $VERSION);
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.03';
+$VERSION = '0.04';
# Path to the config file to load.
$PATH = $ENV{WALLET_CONFIG} || '/etc/wallet/wallet.conf';
@@ -24,6 +23,12 @@ $PATH = $ENV{WALLET_CONFIG} || '/etc/wallet/wallet.conf';
Wallet::Config - Configuration handling for the wallet server
+=for stopwords
+DBI DSN SQLite subdirectories KEYTAB keytab kadmind KDC add-ons kadmin DNS
+SRV kadmin keytabs remctl backend lowercased NETDB ACL NetDB unscoped
+usernames rekey hostnames Allbery wallet-backend keytab-backend Heimdal
+rekeys
+
=head1 SYNOPSIS
use Wallet::Config;
@@ -64,9 +69,9 @@ variable DB_DRIVER to C<MySQL>, use:
$DB_DRIVER = 'MySQL';
-Always remember the initial dollar sign (C<$>) and ending semicolon (C<;>).
-Those familiar with Perl syntax can of course use the full range of Perl
-expressions.
+Always remember the initial dollar sign (C<$>) and ending semicolon
+(C<;>). Those familiar with Perl syntax can of course use the full range
+of Perl expressions.
This configuration file should end with the line:
@@ -81,11 +86,11 @@ file.
=item DB_DRIVER
-Sets the Perl database driver to use for the wallet database. Common values
-would be C<SQLite> or C<MySQL>. Less common values would be C<Oracle>,
-C<Sybase>, or C<ODBC>. The appropriate DBD::* Perl module for the chosen
-driver must be installed and will be dynamically loaded by the wallet. For
-more information, see DBI(3).
+Sets the Perl database driver to use for the wallet database. Common
+values would be C<SQLite> or C<MySQL>. Less common values would be
+C<Oracle>, C<Sybase>, or C<ODBC>. The appropriate DBD::* Perl module for
+the chosen driver must be installed and will be dynamically loaded by the
+wallet. For more information, see DBI(3).
This variable must be set.
@@ -96,8 +101,8 @@ our $DB_DRIVER;
=item DB_INFO
Sets the remaining contents for the DBI DSN (everything after the driver).
-Using this variable provides full control over the connect string passed to
-DBI. When using SQLite, set this variable to the path to the SQLite
+Using this variable provides full control over the connect string passed
+to DBI. When using SQLite, set this variable to the path to the SQLite
database. If this variable is set, DB_NAME, DB_HOST, and DB_PORT are
ignored. For more information, see DBI(3) and the documentation for the
database driver you're using.
@@ -112,9 +117,10 @@ our $DB_INFO;
=item DB_NAME
If DB_INFO is not set, specifies the database name. The third part of the
-DBI connect string will be set to C<database=DB_NAME>, possibly with a host
-and port appended if DB_HOST and DB_PORT are set. For more information, see
-DBI(3) and the documentation for the database driver you're using.
+DBI connect string will be set to C<database=DB_NAME>, possibly with a
+host and port appended if DB_HOST and DB_PORT are set. For more
+information, see DBI(3) and the documentation for the database driver
+you're using.
Either DB_INFO or DB_NAME must be set.
@@ -125,8 +131,8 @@ our $DB_NAME;
=item DB_HOST
If DB_INFO is not set, specifies the database host. C<;host=DB_HOST> will
-be appended to the DBI connect string. For more information, see DBI(3) and
-the documentation for the database driver you're using.
+be appended to the DBI connect string. For more information, see DBI(3)
+and the documentation for the database driver you're using.
=cut
@@ -136,8 +142,8 @@ our $DB_HOST;
If DB_PORT is not set, specifies the database port. C<;port=DB_PORT> will
be appended to the DBI connect string. If this variable is set, DB_HOST
-should also be set. For more information, see DBI(3) and the documentation
-for the database driver you're using.
+should also be set. For more information, see DBI(3) and the
+documentation for the database driver you're using.
=cut
@@ -154,8 +160,8 @@ our $DB_USER;
=item DB_PASSWORD
-Specifies the password for database authentication. Some database backends,
-particularly SQLite, do not need this.
+Specifies the password for database authentication. Some database
+backends, particularly SQLite, do not need this.
=cut
@@ -206,9 +212,10 @@ C<keytab> object type (the Wallet::Object::Keytab class).
=item KEYTAB_FILE
Specifies the keytab to use to authenticate to B<kadmind>. The principal
-whose key is stored in this keytab must have the ability to create, modify,
-inspect, and delete any principals that should be managed by the wallet.
-(In MIT Kerberos F<kadm5.acl> parlance, this is C<admci> privileges.)
+whose key is stored in this keytab must have the ability to create,
+modify, inspect, and delete any principals that should be managed by the
+wallet. (In MIT Kerberos F<kadm5.acl> parlance, this is C<admci>
+privileges.)
KEYTAB_FILE must be set to use keytab objects.
@@ -219,12 +226,13 @@ our $KEYTAB_FILE;
=item KEYTAB_FLAGS
These flags, if any, are passed to the C<addprinc> command when creating a
-new principal in the Kerberos KDC. To not pass any flags, set KEYTAB_FLAGS
-to the empty string. The default value is C<-clearpolicy>, which clears any
-password strength policy from principals created by the wallet. (Since the
-wallet randomizes the keys, password strength checking is generally
-pointless and may interact poorly with the way C<addprinc -randkey> works
-when third-party add-ons for password strength checking are used.)
+new principal in the Kerberos KDC. To not pass any flags, set
+KEYTAB_FLAGS to the empty string. The default value is C<-clearpolicy>,
+which clears any password strength policy from principals created by the
+wallet. (Since the wallet randomizes the keys, password strength checking
+is generally pointless and may interact poorly with the way C<addprinc
+-randkey> works when third-party add-ons for password strength checking
+are used.)
=cut
@@ -251,14 +259,23 @@ default PATH.
our $KEYTAB_KADMIN = 'kadmin';
+=item KEYTAB_KRBTYPE
+
+The Kerberos KDC implementation type, either C<Heimdal> or C<MIT>
+(case-insensitive). KEYTAB_KRBTYPE must be set to use keytab objects.
+
+=cut
+
+our $KEYTAB_KRBTYPE;
+
=item KEYTAB_PRINCIPAL
The principal whose key is stored in KEYTAB_FILE. The wallet will
authenticate as this principal to the kadmin service.
-KEYTAB_PRINCIPAL must be set to use keytab objects, at least until B<kadmin>
-is smart enough to use the first principal found in the keytab it's using
-for authentication.
+KEYTAB_PRINCIPAL must be set to use keytab objects, at least until
+B<kadmin> is smart enough to use the first principal found in the keytab
+it's using for authentication.
=cut
@@ -281,11 +298,11 @@ our $KEYTAB_REALM;
=item KEYTAB_TMP
A directory into which the wallet can write keytabs temporarily while
-processing C<get> commands from clients. The keytabs are written into this
-directory with predictable names, so this should not be a system temporary
-directory such as F</tmp> or F</var/tmp>. It's best to create a directory
-solely for this purpose that's owned by the user the wallet server will run
-as.
+processing C<get> commands from clients. The keytabs are written into
+this directory with predictable names, so this should not be a system
+temporary directory such as F</tmp> or F</var/tmp>. It's best to create a
+directory solely for this purpose that's owned by the user the wallet
+server will run as.
KEYTAB_TMP must be set to use keytab objects.
@@ -297,20 +314,28 @@ our $KEYTAB_TMP;
=head2 Retrieving Existing Keytabs
-The keytab object backend optionally supports retrieving existing keys, and
-hence keytabs, for Kerberos principals by contacting the KDC via remctl and
-talking to B<keytab-backend>. This is enabled by setting the C<unchanging>
-flag on keytab objects. To configure that support, set the following
-variables.
+Heimdal provides the choice, over the network protocol, of either
+downloading the existing keys for a principal or generating new random
+keys. MIT Kerberos does not; downloading a keytab over the kadmin
+protocol always rekeys the principal.
+
+For MIT Kerberos, the keytab object backend therefore optionally supports
+retrieving existing keys, and hence keytabs, for Kerberos principals by
+contacting the KDC via remctl and talking to B<keytab-backend>. This is
+enabled by setting the C<unchanging> flag on keytab objects. To configure
+that support, set the following variables.
+
+This is not required for Heimdal; for Heimdal, setting the C<unchanging>
+flag is all that's needed.
=over 4
=item KEYTAB_REMCTL_CACHE
-Specifies the ticket cache to use when retrieving existing keytabs from the
-KDC. This is only used to implement support for the C<unchanging> flag.
-The ticket cache must be for a principal with access to run C<keytab
-retrieve> via remctl on KEYTAB_REMCTL_HOST.
+Specifies the ticket cache to use when retrieving existing keytabs from
+the KDC. This is only used to implement support for the C<unchanging>
+flag. The ticket cache must be for a principal with access to run
+C<keytab retrieve> via remctl on KEYTAB_REMCTL_HOST.
=cut
@@ -318,10 +343,10 @@ our $KEYTAB_REMCTL_CACHE;
=item KEYTAB_REMCTL_HOST
-The host to which to connect with remctl to retrieve existing keytabs. This
-is only used to implement support for the C<unchanging> flag. This host
-must provide the C<keytab retrieve> command and KEYTAB_REMCTL_CACHE must
-also be set to a ticket cache for a principal with access to run that
+The host to which to connect with remctl to retrieve existing keytabs.
+This is only used to implement support for the C<unchanging> flag. This
+host must provide the C<keytab retrieve> command and KEYTAB_REMCTL_CACHE
+must also be set to a ticket cache for a principal with access to run that
command.
=cut
@@ -331,9 +356,10 @@ our $KEYTAB_REMCTL_HOST;
=item KEYTAB_REMCTL_PRINCIPAL
The service principal to which to authenticate when retrieving existing
-keytabs. This is only used to implement support for the C<unchanging> flag.
-If this variable is not set, the default is formed by prepending C<host/> to
-KEYTAB_REMCTL_HOST. (Note that KEYTAB_REMCTL_HOST is not lowercased first.)
+keytabs. This is only used to implement support for the C<unchanging>
+flag. If this variable is not set, the default is formed by prepending
+C<host/> to KEYTAB_REMCTL_HOST. (Note that KEYTAB_REMCTL_HOST is not
+lowercased first.)
=cut
@@ -352,102 +378,23 @@ our $KEYTAB_REMCTL_PORT;
=back
-=head2 Synchronization with AFS kaserver
-
-The keytab backend optionally supports synchronizing keys between the
-Kerberos v5 realm and a Kerberos v4 realm using kaserver. This
-synchronization is done using B<kasetkey> and is controlled by the C<sync>
-attribute on keytab objects. To configure that support, set the following
-variables.
-
-=over 4
-
-=item KEYTAB_AFS_ADMIN
-
-The Kerberos v4 principal to use for authentication to the AFS kaserver. If
-this principal is not in the default local Kerberos v4 realm, it must be
-fully qualified. A srvtab for this principal must be stored in the path set
-in $KEYTAB_AFS_SRVTAB. This principal must have the ADMIN flag set in the
-AFS kaserver so that it can create and remove principals. This variable
-must be set to use the kaserver synchronization support.
-
-=cut
-
-our $KEYTAB_AFS_ADMIN;
-
-=item KEYTAB_AFS_DESTROY
-
-If this variable, which is false by default, is set to a true value, each
-time a keytab object that is not configured to be synchronized with the AFS
-kaserver, the corresponding Kerberos v4 principal will be deleted from the
-AFS kaserver. Use this with caution; it will cause the AFS kaserver realm
-to be slowly stripped of principals. This is intended for use with
-migration from Kerberos v4 to Kerberos v5, where the old principals should
-be deleted out of Kerberos v4 whenever not requested from the wallet to aid
-in tracking down and removing any systems with lingering Kerberos v4
-dependencies.
-
-Be aware that multiple Kerberos v5 principals map to the same Kerberos v4
-principal since in Kerberos v4 the domain name is stripped from the
-principal for machine principals. If you create a keytab named
-host/foo.example.com and mark it synchronized, and then create another
-keytab named host/foo.example.net and don't mark it synchronized,
-downloading the second will destroy the Kerberos v4 principal of the first
-if this variable is set.
-
-=cut
-
-our $KEYTAB_AFS_DESTROY;
-
-=item KEYTAB_AFS_KASETKEY
-
-The path to the B<kasetkey> command-line client. The default value is
-C<kasetkey>, which will cause the wallet to search for B<kasetkey> on its
-default PATH.
-
-=cut
-
-our $KEYTAB_AFS_KASETKEY = 'kasetkey';
-
-=item KEYTAB_AFS_REALM
-
-The name of the Kerberos v4 realm with which to synchronize keys. This is a
-realm, not a cell, so it should be in all uppercase. If this variable is
-not set, the default is the realm determined from the local cell name.
-
-=cut
-
-our $KEYTAB_AFS_REALM;
-
-=item KEYTAB_AFS_SRVTAB
-
-The path to a srvtab used to authenticate to the AFS kaserver. This srvtab
-should be for the principal set in $KEYTAB_AFS_ADMIN. This variable must be
-set to use the kaserver synchronization support.
-
-=cut
-
-our $KEYTAB_AFS_SRVTAB;
-
-=back
-
=head1 NETDB ACL CONFIGURATION
These configuration variables are only needed if you intend to use the
C<netdb> ACL type (the Wallet::ACL::NetDB class). They specify the remctl
connection information for retrieving user roles from NetDB and the local
-realm to remove from principals (since NetDB normally expects unscoped local
-usernames).
+realm to remove from principals (since NetDB normally expects unscoped
+local usernames).
=over 4
=item NETDB_REALM
The wallet uses fully-qualified principal names (including the realm), but
-NetDB normally expects local usernames without the realm. If this variable
-is set, the given realm will be stripped from any principal names before
-passing them to NetDB. Principals in other realms will be passed to NetDB
-without modification.
+NetDB normally expects local usernames without the realm. If this
+variable is set, the given realm will be stripped from any principal names
+before passing them to NetDB. Principals in other realms will be passed
+to NetDB without modification.
=cut
@@ -456,9 +403,9 @@ our $NETDB_REALM;
=item NETDB_REMCTL_CACHE
Specifies the ticket cache to use when querying the NetDB remctl interface
-for user roles. The ticket cache must be for a principal with access to run
-C<netdb node-roles> via remctl on KEYTAB_REMCTL_HOST. This variable must be
-set to use NetDB ACLs.
+for user roles. The ticket cache must be for a principal with access to
+run C<netdb node-roles> via remctl on KEYTAB_REMCTL_HOST. This variable
+must be set to use NetDB ACLs.
=cut
@@ -477,10 +424,10 @@ our $NETDB_REMCTL_HOST;
=item NETDB_REMCTL_PRINCIPAL
-The service principal to which to authenticate when querying NetDB for user
-roles. If this variable is not set, the default is formed by prepending
-C<host/> to NETDB_REMCTL_HOST. (Note that NETDB_REMCTL_HOST is not
-lowercased first.)
+The service principal to which to authenticate when querying NetDB for
+user roles. If this variable is not set, the default is formed by
+prepending C<host/> to NETDB_REMCTL_HOST. (Note that NETDB_REMCTL_HOST is
+not lowercased first.)
=cut
@@ -488,9 +435,9 @@ our $NETDB_REMCTL_PRINCIPAL;
=item NETDB_REMCTL_PORT
-The port on NETDB_REMCTL_HOST to which to connect with remctl to query NetDB
-for user roles. If this variable is not set, the default remctl port will
-be used.
+The port on NETDB_REMCTL_HOST to which to connect with remctl to query
+NetDB for user roles. If this variable is not set, the default remctl
+port will be used.
=cut
@@ -501,17 +448,18 @@ our $NETDB_REMCTL_PORT;
=head1 DEFAULT OWNERS
By default, only users in the ADMIN ACL can create new objects in the
-wallet. To allow other users to create new objects, define a Perl function
-named default_owner. This function will be called whenever a non-ADMIN user
-tries to create a new object and will be passed the type and name of the
-object. It should return undef if there is no default owner for that
-object. If there is, it should return a list containing the name to use for
-the ACL and then zero or more anonymous arrays of two elements each giving
-the type and identifier for each ACL entry.
-
-For example, the following simple function says to use a default owner named
-C<default> with one entry of type C<krb5> and identifier C<rra@example.com>
-for the object with type C<keytab> and name C<host/example.com>:
+wallet. To allow other users to create new objects, define a Perl
+function named default_owner. This function will be called whenever a
+non-ADMIN user tries to create a new object and will be passed the type
+and name of the object. It should return undef if there is no default
+owner for that object. If there is, it should return a list containing
+the name to use for the ACL and then zero or more anonymous arrays of two
+elements each giving the type and identifier for each ACL entry.
+
+For example, the following simple function says to use a default owner
+named C<default> with one entry of type C<krb5> and identifier
+C<rra@example.com> for the object with type C<keytab> and name
+C<host/example.com>:
sub default_owner {
my ($type, $name) = @_;
@@ -524,8 +472,8 @@ for the object with type C<keytab> and name C<host/example.com>:
Of course, normally this function is used for more complex mappings. Here
is a more complete example. For objects of type keytab corresponding to
-various types of per-machine principals, return a default owner that sets as
-owner anyone with a NetDB role for that system and the system's host
+various types of per-machine principals, return a default owner that sets
+as owner anyone with a NetDB role for that system and the system's host
principal. This permits authorization management using NetDB while also
allowing the system to bootstrap itself once the host principal has been
downloaded and rekey itself using the old host principal.
@@ -545,17 +493,19 @@ downloaded and rekey itself using the old host principal.
return ($acl_name, @acl);
}
-The auto-created ACL used for the owner of the new object will, in the above
-example, be named C<host/I<system>> where I<system> is the fully-qualified
-name of the system as derived from the keytab being requested.
-
-If the name of the ACL returned by the default_owner function matches an ACL
-that already exists in the wallet database, the existing ACL will be
-compared to the default ACL returned by the default_owner function. If the
-existing ACL has the same entries as the one returned by default_owner,
-creation continues if the user is authorized by that ACL. If they don't
-match, creation of the object is rejected, since the presence of an existing
-ACL may indicate that something different is being done with this object.
+The auto-created ACL used for the owner of the new object will, in the
+above example, be named C<host/I<system>> where I<system> is the
+fully-qualified name of the system as derived from the keytab being
+requested.
+
+If the name of the ACL returned by the default_owner function matches an
+ACL that already exists in the wallet database, the existing ACL will be
+compared to the default ACL returned by the default_owner function. If
+the existing ACL has the same entries as the one returned by
+default_owner, creation continues if the user is authorized by that ACL.
+If they don't match, creation of the object is rejected, since the
+presence of an existing ACL may indicate that something different is being
+done with this object.
=head1 NAMING ENFORCEMENT
diff --git a/perl/Wallet/Database.pm b/perl/Wallet/Database.pm
index 3edf059..7b3474a 100644
--- a/perl/Wallet/Database.pm
+++ b/perl/Wallet/Database.pm
@@ -1,5 +1,4 @@
# Wallet::Database -- Wallet system database connection management.
-# $Id$
#
# This module is a thin wrapper around DBI to handle determination of the
# database driver and configuration settings automatically on connect. The
@@ -7,7 +6,7 @@
# like DBI objects in the rest of the code.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -40,7 +39,7 @@ use Wallet::Config;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.01';
+$VERSION = '0.02';
##############################################################################
# Core overrides
@@ -85,6 +84,9 @@ __END__
Wallet::Dabase - Wrapper module for wallet database connections
+=for stopwords
+DBI RaiseError PrintError AutoCommit Allbery
+
=head1 SYNOPSIS
use Wallet::Database;
@@ -94,9 +96,9 @@ Wallet::Dabase - Wrapper module for wallet database connections
Wallet::Database is a thin wrapper module around DBI that takes care of
building a connect string and setting database options based on wallet
-configuration. The only overriden method is connect(). All other methods
-should work the same as in DBI and Wallet::Database objects should be
-usable exactly as if they were DBI objects.
+configuration. The only overridden method is connect(). All other
+methods should work the same as in DBI and Wallet::Database objects should
+be usable exactly as if they were DBI objects.
connect() will obtain the database connection information from the wallet
configuration; see Wallet::Config(3) for more details. It will also
@@ -121,8 +123,8 @@ configuration.
DBI(3), Wallet::Config(3)
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/Kadmin.pm b/perl/Wallet/Kadmin.pm
new file mode 100644
index 0000000..074dd1e
--- /dev/null
+++ b/perl/Wallet/Kadmin.pm
@@ -0,0 +1,239 @@
+# Wallet::Kadmin -- Kerberos administration API for wallet keytab backend.
+#
+# Written by Jon Robertson <jonrober@stanford.edu>
+# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+##############################################################################
+# Modules and declarations
+##############################################################################
+
+package Wallet::Kadmin;
+require 5.006;
+
+use strict;
+use vars qw($VERSION);
+
+use Wallet::Config ();
+
+# This version should be increased on any code change to this module. Always
+# use two digits for the minor version with a leading zero if necessary so
+# that it will sort properly.
+$VERSION = '0.03';
+
+##############################################################################
+# Utility functions for child classes
+##############################################################################
+
+# Read the entirety of a possibly binary file and return the contents,
+# deleting the file after reading it. If reading the file fails, set the
+# error message and return undef.
+sub read_keytab {
+ my ($self, $file) = @_;
+ local *TMPFILE;
+ unless (open (TMPFILE, '<', $file)) {
+ $self->error ("cannot open temporary file $file: $!");
+ return;
+ }
+ local $/;
+ undef $!;
+ my $data = <TMPFILE>;
+ if ($!) {
+ $self->error ("cannot read temporary file $file: $!");
+ unlink $file;
+ return;
+ }
+ close TMPFILE;
+ unlink $file;
+ return $data;
+}
+
+##############################################################################
+# Public methods
+##############################################################################
+
+# Create a new kadmin object, by finding the type requested in the wallet
+# config and passing off to the proper module. Returns the object directly
+# from the specific Wallet::Kadmin::* module.
+sub new {
+ my ($class) = @_;
+ my $kadmin;
+ if (not $Wallet::Config::KEYTAB_KRBTYPE) {
+ die "keytab object implementation not configured\n";
+ } elsif (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'mit') {
+ require Wallet::Kadmin::MIT;
+ $kadmin = Wallet::Kadmin::MIT->new;
+ } elsif (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'heimdal') {
+ require Wallet::Kadmin::Heimdal;
+ $kadmin = Wallet::Kadmin::Heimdal->new;
+ } else {
+ my $type = $Wallet::Config::KEYTAB_KRBTYPE;
+ die "unknown KEYTAB_KRBTYPE setting: $type\n";
+ }
+
+ return $kadmin;
+}
+
+# Set or return the error stashed in the object.
+sub error {
+ my ($self, @error) = @_;
+ if (@error) {
+ my $error = join ('', @error);
+ chomp $error;
+ 1 while ($error =~ s/ at \S+ line \d+\.?\z//);
+ $self->{error} = $error;
+ }
+ return $self->{error};
+}
+
+# Set a callback to be called for forked kadmin processes. This does nothing
+# by default but may be overridden by subclasses that need special behavior
+# (such as the current Wallet::Kadmin::MIT module).
+sub fork_callback { }
+
+1;
+__END__
+
+##############################################################################
+# Documentation
+##############################################################################
+
+=for stopwords
+backend Kadmin keytabs keytab Heimdal API kadmind kadmin KDC ENCTYPE
+enctypes enctype Allbery
+
+=head1 NAME
+
+Wallet::Kadmin - Kerberos administration API for wallet keytab backend
+
+=head1 SYNOPSIS
+
+ my $kadmin = Wallet::Kadmin->new;
+ $kadmin->create ('host/foo.example.com');
+ my $data = $kadmin->keytab_rekey ('host/foo.example.com',
+ 'aes256-cts-hmac-sha1-96');
+ $data = $kadmin->keytab ('host/foo.example.com');
+ my $exists = $kadmin->exists ('host/oldshell.example.com');
+ $kadmin->destroy ('host/oldshell.example.com') if $exists;
+
+=head1 DESCRIPTION
+
+Wallet::Kadmin is a wrapper and base class for modules that provide an
+interface for wallet to do Kerberos administration, specifically create
+and delete principals and create keytabs for a principal. Each subclass
+administers a specific type of Kerberos implementation, such as MIT
+Kerberos or Heimdal, providing a standard set of API calls used to
+interact with that implementation's kadmin interface.
+
+The class uses Wallet::Config to find which type of kadmin interface is in
+use and then returns an object to use for interacting with that interface.
+See L<Wallet::Config/"KEYTAB OBJECT CONFIGURATION"> for details on how to
+configure this module.
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item new()
+
+Finds the proper Kerberos implementation and calls the new() constructor
+for that implementation's module, returning the resulting object. If the
+implementation is not recognized or set, die with an error message.
+
+=back
+
+=head1 INSTANCE METHODS
+
+These methods are provided by any object returned by new(), regardless of
+the underlying kadmin interface. They are implemented by the child class
+appropriate for the configured Kerberos implementation.
+
+=over 4
+
+=item create(PRINCIPAL)
+
+Adds a new principal with a given name. The principal is created with a
+random password, and any other flags set by Wallet::Config. Returns true
+on success and false on failure. If the principal already exists, return
+true as we are bringing our expectations in line with reality.
+
+=item destroy(PRINCIPAL)
+
+Removes a principal with the given name. Returns true on success or false
+on failure. If the principal does not exist, return true as we are
+bringing our expectations in line with reality.
+
+=item error([ERROR ...])
+
+Returns the error of the last failing operation or undef if no operations
+have failed. Callers should call this function to get the error message
+after an undef return from any other instance method.
+
+For the convenience of child classes, this method can also be called with
+one or more error strings. If so, those strings are concatenated
+together, trailing newlines are removed, any text of the form S<C< at \S+
+line \d+\.?>> at the end of the message is stripped off, and the result is
+stored as the error. Only child classes should call this method with an
+error string.
+
+=item exists(PRINCIPAL)
+
+Returns true if the given principal exists in the KDC and C<0> if it
+doesn't. If an error is encountered in checking whether the principal
+exists, exists() returns undef.
+
+=item fork_callback(CALLBACK)
+
+If the module has to fork an external process for some reason, such as a
+kadmin command-line client, the sub CALLBACK will be called in the child
+process before running the program. This can be used to, for example,
+properly clean up shared database handles.
+
+=item keytab(PRINCIPAL)
+
+keytab() creates a keytab for the given principal, storing it in the given
+file. A keytab is an on-disk store for the key or keys for a Kerberos
+principal. Keytabs are used by services to verify incoming authentication
+from clients or by automated processes that need to authenticate to
+Kerberos. To create a keytab, the principal has to have previously been
+created in the Kerberos KDC. Returns the keytab as binary data on success
+and undef on failure.
+
+=item keytab_rekey(PRINCIPAL [, ENCTYPE ...])
+
+Like keytab(), but randomizes the key for the principal before generating
+the keytab and writes it to the given file. This will invalidate any
+existing keytabs for that principal. This method can also limit the
+encryption types of the keys for that principal via the optional ENCTYPE
+arguments. The enctype values must be enctype strings recognized by the
+Kerberos implementation (strings like C<aes256-cts-hmac-sha1-96> or
+C<des-cbc-crc>). If none are given, the KDC defaults will be used.
+Returns the keytab as binary data on success and undef on failure.
+
+=back
+
+The following methods are utility methods to aid with child class
+implementation and should only be called by child classes.
+
+=over 4
+
+=item read_keytab(FILE)
+
+Reads the contents of the keytab stored in FILE into memory and returns it
+as binary data. On failure, returns undef and sets the object error.
+
+=back
+
+=head1 SEE ALSO
+
+kadmin(8), Wallet::Config(3), Wallet::Object::Keytab(3), wallet-backend(8)
+
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
+
+=head1 AUTHORS
+
+Jon Robertson <jonrober@stanford.edu> and Russ Allbery <rra@stanford.edu>
+
+=cut
diff --git a/perl/Wallet/Kadmin/Heimdal.pm b/perl/Wallet/Kadmin/Heimdal.pm
new file mode 100644
index 0000000..d1eecda
--- /dev/null
+++ b/perl/Wallet/Kadmin/Heimdal.pm
@@ -0,0 +1,286 @@
+# Wallet::Kadmin::Heimdal -- Wallet Kerberos administration API for Heimdal.
+#
+# Written by Jon Robertson <jonrober@stanford.edu>
+# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+##############################################################################
+# Modules and declarations
+##############################################################################
+
+package Wallet::Kadmin::Heimdal;
+require 5.006;
+
+use strict;
+use vars qw(@ISA $VERSION);
+
+use Heimdal::Kadm5 qw(KRB5_KDB_DISALLOW_ALL_TIX);
+use Wallet::Config ();
+use Wallet::Kadmin ();
+
+@ISA = qw(Wallet::Kadmin);
+
+# This version should be increased on any code change to this module. Always
+# use two digits for the minor version with a leading zero if necessary so
+# that it will sort properly.
+$VERSION = '0.03';
+
+##############################################################################
+# Utility functions
+##############################################################################
+
+# Add the realm to the end of the principal if no realm is currently present.
+sub canonicalize_principal {
+ my ($self, $principal) = @_;
+ if ($Wallet::Config::KEYTAB_REALM && $principal !~ /\@/) {
+ $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
+ }
+ return $principal;
+}
+
+##############################################################################
+# Public interfaces
+##############################################################################
+
+# Check whether a given principal already exists in Kerberos. Returns true if
+# so, false otherwise.
+sub exists {
+ my ($self, $principal) = @_;
+ $principal = $self->canonicalize_principal ($principal);
+ my $kadmin = $self->{client};
+ my $princdata = eval { $kadmin->getPrincipal ($principal) };
+ if ($@) {
+ $self->error ("error getting principal: $@");
+ return;
+ }
+ return $princdata ? 1 : 0;
+}
+
+# Create a principal in Kerberos. If there is an error, return undef and set
+# the error. Return 1 on success or the principal already existing.
+sub create {
+ my ($self, $principal) = @_;
+ $principal = $self->canonicalize_principal ($principal);
+ my $exists = eval { $self->exists ($principal) };
+ if ($@) {
+ $self->error ("error adding principal $principal: $@");
+ return;
+ }
+ return 1 if $exists;
+
+ # The way Heimdal::Kadm5 works, we create a principal object, create the
+ # actual principal set inactive, then randomize it and activate it.
+ #
+ # TODO - Paranoia makes me want to set the password to something random
+ # on creation even if it is inactive until after randomized by
+ # module.
+ my $kadmin = $self->{client};
+ eval {
+ my $princdata = $kadmin->makePrincipal ($principal);
+ my $attrs = $princdata->getAttributes;
+ $attrs |= KRB5_KDB_DISALLOW_ALL_TIX;
+ $princdata->setAttributes ($attrs);
+ my $password = 'inactive';
+ $kadmin->createPrincipal ($princdata, $password, 0);
+ $kadmin->randKeyPrincipal ($principal);
+ $kadmin->enablePrincipal ($principal);
+ };
+ if ($@) {
+ $self->error ("error adding principal $principal: $@");
+ return;
+ }
+ return 1;
+}
+
+# Create a keytab for a principal. Returns the keytab as binary data or undef
+# on failure, setting the error.
+sub keytab {
+ my ($self, $principal) = @_;
+ $principal = $self->canonicalize_principal ($principal);
+ my $kadmin = $self->{client};
+ my $file = $Wallet::Config::KEYTAB_TMP . "/keytab.$$";
+ unlink $file;
+ my $princdata = eval { $kadmin->getPrincipal ($principal) };
+ if ($@) {
+ $self->error ("error creating keytab for $principal: $@");
+ return;
+ } elsif (!$princdata) {
+ $self->error ("error creating keytab for $principal: principal does"
+ . " not exist");
+ return;
+ }
+ eval { $kadmin->extractKeytab ($princdata, $file) };
+ if ($@) {
+ $self->error ("error creating keytab for principal: $@");
+ return;
+ }
+ return $self->read_keytab ($file);
+}
+
+# Create a keytab for a principal, randomizing the keys for that principal at
+# the same time. Takes the principal and an optional list of encryption types
+# to which to limit the keytab. Return the keytab data on success and undef
+# on failure. If the keytab creation fails, sets the error.
+sub keytab_rekey {
+ my ($self, $principal, @enctypes) = @_;
+ $principal = $self->canonicalize_principal ($principal);
+
+ # The way Heimdal works, you can only remove enctypes from a principal,
+ # not add them back in. So we need to run randkeyPrincipal first each
+ # time to restore all possible enctypes and then whittle them back down
+ # to those we have been asked for this time.
+ my $kadmin = $self->{client};
+ eval { $kadmin->randKeyPrincipal ($principal) };
+ if ($@) {
+ $self->error ("error creating keytab for $principal: could not"
+ . " reinit enctypes: $@");
+ return;
+ }
+ my $princdata = eval { $kadmin->getPrincipal ($principal) };
+ if ($@) {
+ $self->error ("error creating keytab for $principal: $@");
+ return;
+ } elsif (!$princdata) {
+ $self->error ("error creating keytab for $principal: principal does"
+ . " not exist");
+ return;
+ }
+
+ # Now actually remove any non-requested enctypes, if we requested any.
+ if (@enctypes) {
+ my $alltypes = $princdata->getKeytypes;
+ my %wanted = map { $_ => 1 } @enctypes;
+ for my $key (@{ $alltypes }) {
+ my $keytype = $key->[0];
+ next if exists $wanted{$keytype};
+ eval { $princdata->delKeytypes ($keytype) };
+ if ($@) {
+ $self->error ("error removing keytype $keytype from the"
+ . " keytab: $@");
+ return;
+ }
+ }
+ eval { $kadmin->modifyPrincipal ($princdata) };
+ if ($@) {
+ $self->error ("error saving principal modifications: $@");
+ return;
+ }
+ }
+
+ # Create the keytab.
+ my $file = $Wallet::Config::KEYTAB_TMP . "/keytab.$$";
+ unlink $file;
+ eval { $kadmin->extractKeytab ($princdata, $file) };
+ if ($@) {
+ $self->error ("error creating keytab for principal: $@");
+ return;
+ }
+ return $self->read_keytab ($file);
+}
+
+# Delete a principal from Kerberos. Return true if successful, false
+# otherwise. If the deletion fails, sets the error. If the principal doesn't
+# exist, return success; we're bringing reality in line with our expectations.
+sub destroy {
+ my ($self, $principal) = @_;
+ $principal = $self->canonicalize_principal ($principal);
+ my $exists = eval { $self->exists ($principal) };
+ if ($@) {
+ $self->error ("error checking principal existance: $@");
+ return;
+ } elsif (not $exists) {
+ return 1;
+ }
+ my $kadmin = $self->{client};
+ my $retval = eval { $kadmin->deletePrincipal ($principal) };
+ if ($@) {
+ $self->error ("error deleting $principal: $@");
+ return;
+ }
+ return 1;
+}
+
+# Create a new Wallet::Kadmin::Heimdal object and its underlying
+# Heimdal::Kadm5 object.
+sub new {
+ my ($class) = @_;
+ unless (defined ($Wallet::Config::KEYTAB_PRINCIPAL)
+ and defined ($Wallet::Config::KEYTAB_FILE)
+ and defined ($Wallet::Config::KEYTAB_REALM)) {
+ die "keytab object implementation not configured\n";
+ }
+ unless (defined ($Wallet::Config::KEYTAB_TMP)) {
+ die "KEYTAB_TMP configuration variable not set\n";
+ }
+ my @options = (RaiseError => 1,
+ Principal => $Wallet::Config::KEYTAB_PRINCIPAL,
+ Realm => $Wallet::Config::KEYTAB_REALM,
+ Keytab => $Wallet::Config::KEYTAB_FILE);
+ if ($Wallet::Config::KEYTAB_HOST) {
+ push (@options, Server => $Wallet::Config::KEYTAB_HOST);
+ }
+ my $client = Heimdal::Kadm5::Client->new (@options);
+ my $self = { client => $client };
+ bless ($self, $class);
+ return $self;
+}
+
+1;
+__END__
+
+##############################################################################
+# Documentation
+##############################################################################
+
+=for stopwords
+keytabs keytab kadmin KDC API Allbery Heimdal
+
+=head1 NAME
+
+Wallet::Kadmin::Heimdal - Wallet Kerberos administration API for Heimdal
+
+=head1 SYNOPSIS
+
+ my $kadmin = Wallet::Kadmin::Heimdal->new;
+ $kadmin->create ('host/foo.example.com');
+ $kadmin->keytab_rekey ('host/foo.example.com', 'keytab',
+ 'aes256-cts-hmac-sha1-96');
+ my $data = $kadmin->keytab ('host/foo.example.com');
+ my $exists = $kadmin->exists ('host/oldshell.example.com');
+ $kadmin->destroy ('host/oldshell.example.com') if $exists;
+
+=head1 DESCRIPTION
+
+Wallet::Kadmin::Heimdal implements the Wallet::Kadmin API for Heimdal,
+providing an interface to create and delete principals and create keytabs.
+It provides the API documented in Wallet::Kadmin(3) for a Heimdal KDC.
+
+To use this class, several configuration parameters must be set. See
+L<Wallet::Config/"KEYTAB OBJECT CONFIGURATION"> for details.
+
+=head1 FILES
+
+=over 4
+
+=item KEYTAB_TMP/keytab.<pid>
+
+The keytab is created in this file and then read into memory. KEYTAB_TMP
+is set in the wallet configuration, and <pid> is the process ID of the
+current process. The file is unlinked after being read.
+
+=back
+
+=head1 SEE ALSO
+
+kadmin(8), Wallet::Config(3), Wallet::Kadmin(3),
+Wallet::Object::Keytab(3), wallet-backend(8)
+
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
+
+=head1 AUTHORS
+
+Russ Allbery <rra@stanford.edu> and Jon Robertson <jonrober@stanford.edu>.
+
+=cut
diff --git a/perl/Wallet/Kadmin/MIT.pm b/perl/Wallet/Kadmin/MIT.pm
new file mode 100644
index 0000000..434e93d
--- /dev/null
+++ b/perl/Wallet/Kadmin/MIT.pm
@@ -0,0 +1,322 @@
+# Wallet::Kadmin::MIT -- Wallet Kerberos administration API for MIT.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Pulled into a module by Jon Robertson <jonrober@stanford.edu>
+# Copyright 2007, 2008, 2009, 2010
+# Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+##############################################################################
+# Modules and declarations
+##############################################################################
+
+package Wallet::Kadmin::MIT;
+require 5.006;
+
+use strict;
+use vars qw(@ISA $VERSION);
+
+use Wallet::Config ();
+use Wallet::Kadmin ();
+
+@ISA = qw(Wallet::Kadmin);
+
+# This version should be increased on any code change to this module. Always
+# use two digits for the minor version with a leading zero if necessary so
+# that it will sort properly.
+$VERSION = '0.02';
+
+##############################################################################
+# kadmin Interaction
+##############################################################################
+
+# Make sure that principals are well-formed and don't contain characters that
+# will cause us problems when talking to kadmin. Takes a principal and
+# returns true if it's okay, false otherwise. Note that we do not permit
+# realm information here.
+sub valid_principal {
+ my ($self, $principal) = @_;
+ return scalar ($principal =~ m,^[\w-]+(/[\w_.-]+)?\z,);
+}
+
+# Run a kadmin command and capture the output. Returns the output, either as
+# a list of lines or, in scalar context, as one string. The exit status of
+# kadmin is often worthless.
+sub kadmin {
+ my ($self, $command) = @_;
+ unless (defined ($Wallet::Config::KEYTAB_PRINCIPAL)
+ and defined ($Wallet::Config::KEYTAB_FILE)
+ and defined ($Wallet::Config::KEYTAB_REALM)) {
+ die "keytab object implementation not configured\n";
+ }
+ my @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, '-k', '-t',
+ $Wallet::Config::KEYTAB_FILE, '-q', $command);
+ push (@args, '-s', $Wallet::Config::KEYTAB_HOST)
+ if $Wallet::Config::KEYTAB_HOST;
+ push (@args, '-r', $Wallet::Config::KEYTAB_REALM)
+ if $Wallet::Config::KEYTAB_REALM;
+ my $pid = open (KADMIN, '-|');
+ if (not defined $pid) {
+ $self->error ("cannot fork: $!");
+ return;
+ } elsif ($pid == 0) {
+ $self->{fork_callback} () if $self->{fork_callback};
+ unless (open (STDERR, '>&STDOUT')) {
+ warn "wallet: cannot dup stdout: $!\n";
+ exit 1;
+ }
+ unless (exec ($Wallet::Config::KEYTAB_KADMIN, @args)) {
+ warn "wallet: cannot run $Wallet::Config::KEYTAB_KADMIN: $!\n";
+ exit 1;
+ }
+ }
+ local $_;
+ my @output;
+ while (<KADMIN>) {
+ if (/^wallet: cannot /) {
+ s/^wallet: //;
+ $self->error ($_);
+ return;
+ }
+ push (@output, $_) unless /Authenticating as principal/;
+ }
+ close KADMIN;
+ return wantarray ? @output : join ('', @output);
+}
+
+##############################################################################
+# Public interfaces
+##############################################################################
+
+# Set a callback to be called for forked kadmin processes.
+sub fork_callback {
+ my ($self, $callback) = @_;
+ $self->{fork_callback} = $callback;
+}
+
+# Check whether a given principal already exists in Kerberos. Returns true if
+# so, false otherwise. Returns undef if kadmin fails, with the error already
+# set by kadmin.
+sub exists {
+ my ($self, $principal) = @_;
+ return unless $self->valid_principal ($principal);
+ if ($Wallet::Config::KEYTAB_REALM) {
+ $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
+ }
+ my $output = $self->kadmin ("getprinc $principal");
+ if (!defined $output) {
+ return;
+ } elsif ($output =~ /^get_principal: /) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+# Create a principal in Kerberos. Sets the error and returns undef on failure,
+# and returns 1 on either success or the principal already existing.
+sub create {
+ my ($self, $principal) = @_;
+ unless ($self->valid_principal ($principal)) {
+ $self->error ("invalid principal name $principal");
+ return;
+ }
+ return 1 if $self->exists ($principal);
+ if ($Wallet::Config::KEYTAB_REALM) {
+ $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
+ }
+ my $flags = $Wallet::Config::KEYTAB_FLAGS || '';
+ my $output = $self->kadmin ("addprinc -randkey $flags $principal");
+ if (!defined $output) {
+ return;
+ } elsif ($output =~ /^add_principal: (.*)/m) {
+ $self->error ("error adding principal $principal: $1");
+ return;
+ }
+ return 1;
+}
+
+# Retrieve an existing keytab from the KDC via a remctl call. The KDC needs
+# to be running the keytab-backend script and support the keytab retrieve
+# remctl command. In addition, the user must have configured us with the path
+# to a ticket cache and the host to which to connect with remctl. Returns the
+# keytab on success and undef on failure.
+sub keytab {
+ my ($self, $principal) = @_;
+ my $host = $Wallet::Config::KEYTAB_REMCTL_HOST;
+ unless ($host and $Wallet::Config::KEYTAB_REMCTL_CACHE) {
+ $self->error ('keytab unchanging support not configured');
+ return;
+ }
+ eval { require Net::Remctl };
+ if ($@) {
+ $self->error ("keytab unchanging support not available: $@");
+ return;
+ }
+ if ($principal !~ /\@/ && $Wallet::Config::KEYTAB_REALM) {
+ $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
+ }
+ local $ENV{KRB5CCNAME} = $Wallet::Config::KEYTAB_REMCTL_CACHE;
+ my $port = $Wallet::Config::KEYTAB_REMCTL_PORT || 0;
+ my $remctl_princ = $Wallet::Config::KEYTAB_REMCTL_PRINCIPAL || '';
+ my @command = ('keytab', 'retrieve', $principal);
+ my $result = Net::Remctl::remctl ($host, $port, $remctl_princ, @command);
+ if ($result->error) {
+ $self->error ("cannot retrieve keytab for $principal: ",
+ $result->error);
+ return;
+ } elsif ($result->status != 0) {
+ my $error = $result->stderr;
+ $error =~ s/\s+$//;
+ $error =~ s/\n/ /g;
+ $self->error ("cannot retrieve keytab for $principal: $error");
+ return;
+ } else {
+ return $result->stdout;
+ }
+}
+
+# Create a keytab for a principal, randomizing the keys for that principal
+# in the process. Takes the principal and an optional list of encryption
+# types to which to limit the keytab. Return the keytab data on success
+# and undef otherwise. If the keytab creation fails, sets the error.
+sub keytab_rekey {
+ my ($self, $principal, @enctypes) = @_;
+ unless ($self->valid_principal ($principal)) {
+ $self->error ("invalid principal name: $principal");
+ return;
+ }
+ if ($Wallet::Config::KEYTAB_REALM) {
+ $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
+ }
+ my $file = $Wallet::Config::KEYTAB_TMP . "/keytab.$$";
+ unlink $file;
+ my $command = "ktadd -q -k $file";
+ if (@enctypes) {
+ @enctypes = map { /:/ ? $_ : "$_:normal" } @enctypes;
+ $command .= ' -e "' . join (' ', @enctypes) . '"';
+ }
+ my $output = $self->kadmin ("$command $principal");
+ if (!defined $output) {
+ return;
+ } elsif ($output =~ /^(?:kadmin|ktadd): (.*)/m) {
+ $self->error ("error creating keytab for $principal: $1");
+ return;
+ }
+ return $self->read_keytab ($file);
+}
+
+# Delete a principal from Kerberos. Return true if successful, false
+# otherwise. If the deletion fails, sets the error. If the principal doesn't
+# exist, return success; we're bringing reality in line with our expectations.
+sub destroy {
+ my ($self, $principal) = @_;
+ unless ($self->valid_principal ($principal)) {
+ $self->error ("invalid principal name: $principal");
+ }
+ my $exists = $self->exists ($principal);
+ if (!defined $exists) {
+ return;
+ } elsif (not $exists) {
+ return 1;
+ }
+ if ($Wallet::Config::KEYTAB_REALM) {
+ $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
+ }
+ my $output = $self->kadmin ("delprinc -force $principal");
+ if (!defined $output) {
+ return;
+ } elsif ($output =~ /^delete_principal: (.*)/m) {
+ $self->error ("error deleting $principal: $1");
+ return;
+ }
+ return 1;
+}
+
+# Create a new MIT kadmin object. Very empty for the moment, but later it
+# will probably fill out if we go to using a module rather than calling
+# kadmin directly.
+sub new {
+ my ($class) = @_;
+ unless (defined ($Wallet::Config::KEYTAB_TMP)) {
+ die "KEYTAB_TMP configuration variable not set\n";
+ }
+ my $self = {};
+ bless ($self, $class);
+ return $self;
+}
+
+1;
+__END__
+
+##############################################################################
+# Documentation
+##############################################################################
+
+=for stopwords
+rekeying rekeys remctl backend keytabs keytab kadmin KDC API Allbery
+
+=head1 NAME
+
+Wallet::Kadmin::MIT - Wallet Kerberos administration API for MIT
+
+=head1 SYNOPSIS
+
+ my $kadmin = Wallet::Kadmin::MIT->new;
+ $kadmin->create ('host/foo.example.com');
+ my $data = $kadmin->keytab_rekey ('host/foo.example.com',
+ 'aes256-cts-hmac-sha1-96');
+ $data = $kadmin->keytab ('host/foo.example.com');
+ my $exists = $kadmin->exists ('host/oldshell.example.com');
+ $kadmin->destroy ('host/oldshell.example.com') if $exists;
+
+=head1 DESCRIPTION
+
+Wallet::Kadmin::MIT implements the Wallet::Kadmin API for MIT Kerberos,
+providing an interface to create and delete principals and create keytabs.
+It provides the API documented in Wallet::Kadmin(3) for an MIT Kerberos
+KDC.
+
+MIT Kerberos does not provide any method via the kadmin network protocol
+to retrieve a keytab for a principal without rekeying it, so the keytab()
+method (as opposed to keytab_rekey(), which rekeys the principal) is
+implemented using a remctl backend. For that method (used for unchanging
+keytab objects) to work, the necessary wallet configuration and remctl
+interface on the KDC must be set up.
+
+To use this class, several configuration parameters must be set. See
+L<Wallet::Config/"KEYTAB OBJECT CONFIGURATION"> for details.
+
+=head1 FILES
+
+=over 4
+
+=item KEYTAB_TMP/keytab.<pid>
+
+The keytab is created in this file and then read into memory. KEYTAB_TMP
+is set in the wallet configuration, and <pid> is the process ID of the
+current process. The file is unlinked after being read.
+
+=back
+
+=head1 LIMITATIONS
+
+Currently, this implementation calls an external B<kadmin> program rather
+than using a native Perl module and therefore requires B<kadmin> be
+installed and parses its output. It may miss some error conditions if the
+output of B<kadmin> ever changes.
+
+=head1 SEE ALSO
+
+kadmin(8), Wallet::Config(3), Wallet::Kadmin(3),
+Wallet::Object::Keytab(3), wallet-backend(8)
+
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
+
+=head1 AUTHORS
+
+Russ Allbery <rra@stanford.edu> and Jon Robertson <jonrober@stanford.edu>.
+
+=cut
diff --git a/perl/Wallet/Object/Base.pm b/perl/Wallet/Object/Base.pm
index bc4f096..5097729 100644
--- a/perl/Wallet/Object/Base.pm
+++ b/perl/Wallet/Object/Base.pm
@@ -1,8 +1,7 @@
# Wallet::Object::Base -- Parent class for any object stored in the wallet.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -23,7 +22,7 @@ use Wallet::ACL;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.04';
+$VERSION = '0.05';
##############################################################################
# Constructors
@@ -446,6 +445,22 @@ sub flag_set {
# History
##############################################################################
+# Expand a given ACL id to add its name, for readability. Returns the
+# original id alone if there was a problem finding the name.
+sub format_acl_id {
+ my ($self, $id) = @_;
+ my $name = $id;
+
+ my $sql = 'select ac_name from acls where ac_id = ?';
+ my $sth = $self->{dbh}->prepare ($sql);
+ $sth->execute ($id);
+ if (my @ref = $sth->fetchrow_array) {
+ $name = $ref[0] . " ($id)";
+ }
+
+ return $name;
+}
+
# Return the formatted history for a given object or undef on error.
# Currently always returns the complete history, but eventually will need to
# provide some way of showing only recent entries.
@@ -477,6 +492,18 @@ sub history {
} elsif (defined ($new)) {
$output .= "add $new to attribute $attr";
}
+ } elsif ($data[0] eq 'set'
+ and ($data[1] eq 'owner' or $data[1] =~ /^acl_/)) {
+ my $field = $data[1];
+ $old = $self->format_acl_id ($old) if defined ($old);
+ $new = $self->format_acl_id ($new) if defined ($new);
+ if (defined ($old) and defined ($new)) {
+ $output .= "set $field to $new (was $old)";
+ } elsif (defined ($new)) {
+ $output .= "set $field to $new";
+ } elsif (defined ($old)) {
+ $output .= "unset $field (was $old)";
+ }
} elsif ($data[0] eq 'set') {
my $field = $data[1];
if (defined ($old) and defined ($new)) {
@@ -642,6 +669,10 @@ __END__
Wallet::Object::Base - Generic parent class for wallet objects
+=for stopwords
+DBH HOSTNAME DATETIME ACL backend metadata timestamp Allbery wallet-backend
+backend-specific
+
=head1 SYNOPSIS
package Wallet::Object::Simple;
@@ -655,104 +686,107 @@ Wallet::Object::Base - Generic parent class for wallet objects
=head1 DESCRIPTION
Wallet::Object::Base is the generic parent class for wallet objects (data
-types that can be stored in the wallet system). It provides defualt
+types that can be stored in the wallet system). It provides default
functions and behavior, including handling generic object settings. All
handlers for objects stored in the wallet should inherit from it. It is
not used directly.
=head1 PUBLIC CLASS METHODS
-The following methods are called by the rest of the wallet system and should
-be implemented by all objects stored in the wallet. They should be called
-with the desired wallet object class as the first argument (generally using
-the Wallet::Object::Type->new syntax).
+The following methods are called by the rest of the wallet system and
+should be implemented by all objects stored in the wallet. They should be
+called with the desired wallet object class as the first argument
+(generally using the Wallet::Object::Type->new syntax).
=over 4
=item new(TYPE, NAME, DBH)
Creates a new object with the given object type and name, based on data
-already in the database. This method will only succeed if an object of the
-given TYPE and NAME is already present in the wallet database. If no such
-object exits, throws an exception. Otherwise, returns an object blessed
-into the class used for the new() call (so subclasses can leave this method
-alone and not override it).
+already in the database. This method will only succeed if an object of
+the given TYPE and NAME is already present in the wallet database. If no
+such object exits, throws an exception. Otherwise, returns an object
+blessed into the class used for the new() call (so subclasses can leave
+this method alone and not override it).
-Takes a Wallet::Database object, which is stored in the object and used for
-any further operations.
+Takes a Wallet::Database object, which is stored in the object and used
+for any further operations.
=item create(TYPE, NAME, DBH, PRINCIPAL, HOSTNAME [, DATETIME])
Similar to new() but instead creates a new entry in the database. This
method will throw an exception if an entry for that type and name already
-exists in the database or if creating the database record fails. Otherwise,
-a new database entry will be created with that type and name, no owner, no
-ACLs, no expiration, no flags, and with created by, from, and on set to the
-PRINCIPAL, HOSTNAME, and DATETIME parameters. If DATETIME isn't given, the
-current time is used. The database handle is treated as with new().
+exists in the database or if creating the database record fails.
+Otherwise, a new database entry will be created with that type and name,
+no owner, no ACLs, no expiration, no flags, and with created by, from, and
+on set to the PRINCIPAL, HOSTNAME, and DATETIME parameters. If DATETIME
+isn't given, the current time is used. The database handle is treated as
+with new().
=back
=head1 PUBLIC INSTANCE METHODS
The following methods may be called on instantiated wallet objects.
-Normally, the only methods that a subclass will need to override are get(),
-store(), show(), and destroy().
+Normally, the only methods that a subclass will need to override are
+get(), store(), show(), and destroy().
-If the locked flag is set on an object, no actions may be performed on that
-object except for the flag methods and show(). All other actions will be
-rejected with an error saying the object is locked.
+If the locked flag is set on an object, no actions may be performed on
+that object except for the flag methods and show(). All other actions
+will be rejected with an error saying the object is locked.
=over 4
=item acl(TYPE [, ACL, PRINCIPAL, HOSTNAME [, DATETIME]])
-Sets or retrieves a given object ACL as a numeric ACL ID. TYPE must be one
-of C<get>, C<store>, C<show>, C<destroy>, or C<flags>, corresponding to the
-ACLs kept on an object. If no other arguments are given, returns the
-current ACL setting as an ACL ID or undef if that ACL isn't set. If other
-arguments are given, change that ACL to ACL and return true on success and
-false on failure. Pass in the empty string for ACL to clear the ACL. The
-other arguments are used for logging and history and should indicate the
-user and host from which the change is made and the time of the change.
+Sets or retrieves a given object ACL as a numeric ACL ID. TYPE must be
+one of C<get>, C<store>, C<show>, C<destroy>, or C<flags>, corresponding
+to the ACLs kept on an object. If no other arguments are given, returns
+the current ACL setting as an ACL ID or undef if that ACL isn't set. If
+other arguments are given, change that ACL to ACL and return true on
+success and false on failure. Pass in the empty string for ACL to clear
+the ACL. The other arguments are used for logging and history and should
+indicate the user and host from which the change is made and the time of
+the change.
=item attr(ATTRIBUTE [, VALUES, PRINCIPAL, HOSTNAME [, DATETIME]])
Sets or retrieves a given object attribute. Attributes are used to store
-backend-specific information for a particular object type and ATTRIBUTE must
-be an attribute type known to the underlying object implementation. The
-default implementation of this method rejects all attributes as unknown.
+backend-specific information for a particular object type and ATTRIBUTE
+must be an attribute type known to the underlying object implementation.
+The default implementation of this method rejects all attributes as
+unknown.
If no other arguments besides ATTRIBUTE are given, returns the values of
that attribute, if any, as a list. On error, returns the empty list. To
-distinguish between an error and an empty return, call error() afterwards.
+distinguish between an error and an empty return, call error() afterward.
It is guaranteed to return undef unless there was an error.
If other arguments are given, sets the given ATTRIBUTE values to VALUES,
-which must be a reference to an array (even if only one value is being set).
-Pass a reference to an empty array to clear the attribute values. The other
-arguments are used for logging and history and should indicate the user and
-host from which the change is made and the time of the change. Returns true
-on success and false on failure.
+which must be a reference to an array (even if only one value is being
+set). Pass a reference to an empty array to clear the attribute values.
+The other arguments are used for logging and history and should indicate
+the user and host from which the change is made and the time of the
+change. Returns true on success and false on failure.
=item attr_show()
-Returns a formatted text description of the type-specific attributes of the
-object, or undef on error. The default implementation of this method always
-returns the empty string. If there are any type-specific attributes set,
-this method should return that metadata, formatted as key: value pairs with
-the keys right-aligned in the first 15 characters, followed by a space, a
-colon, and the value.
+Returns a formatted text description of the type-specific attributes of
+the object, or undef on error. The default implementation of this method
+always returns the empty string. If there are any type-specific
+attributes set, this method should return that metadata, formatted as key:
+value pairs with the keys right-aligned in the first 15 characters,
+followed by a space, a colon, and the value.
=item destroy(PRINCIPAL, HOSTNAME [, DATETIME])
Destroys the object by removing all record of it from the database. The
-Wallet::Object::Base implementation handles the generic database work,
-but any subclass should override this method to do any deletion of files
-or entries in external databases and any other database entries and then
-call the parent method to handle the generic database cleanup. Returns
-true on success and false on failure. The arguments are used for logging
-and history and should indicate the user and host from which the change is
+Wallet::Object::Base implementation handles the generic database work, but
+any subclass should override this method to do any deletion of files or
+entries in external databases and any other database entries and then call
+the parent method to handle the generic database cleanup. Returns true on
+success and false on failure. The arguments are used for logging and
+history and should indicate the user and host from which the change is
made and the time of the change.
=item error([ERROR ...])
@@ -762,47 +796,50 @@ have failed. Callers should call this function to get the error message
after an undef return from any other instance method.
For the convenience of child classes, this method can also be called with
-one or more error strings. If so, those strings are concatenated together,
-trailing newlines are removed, any text of the form S<C< at \S+ line
-\d+\.?>> at the end of the message is stripped off, and the result is stored
-as the error. Only child classes should call this method with an error
-string.
+one or more error strings. If so, those strings are concatenated
+together, trailing newlines are removed, any text of the form S<C< at \S+
+line \d+\.?>> at the end of the message is stripped off, and the result is
+stored as the error. Only child classes should call this method with an
+error string.
=item expires([EXPIRES, PRINCIPAL, HOSTNAME [, DATETIME]])
Sets or retrieves the expiration date of an object. If no arguments are
-given, returns the current expiration or undef if no expiration is set. If
-arguments are given, change the expiration to EXPIRES and return true on
-success and false on failure. EXPIRES must be in the format C<YYYY-MM-DD
-HH:MM:SS>, although the time portion may be omitted. Pass in the empty
-string for EXPIRES to clear the expiration date.
-
-The other arguments are used for logging and history and should indicate the
-user and host from which the change is made and the time of the change.
+given, returns the current expiration or undef if no expiration is set.
+If arguments are given, change the expiration to EXPIRES and return true
+on success and false on failure. EXPIRES must be in the format
+C<YYYY-MM-DD HH:MM:SS>, although the time portion may be omitted. Pass in
+the empty string for EXPIRES to clear the expiration date.
+
+The other arguments are used for logging and history and should indicate
+the user and host from which the change is made and the time of the
+change.
=item flag_check(FLAG)
-Check whether the given flag is set on an object. Returns true if set, C<0>
-if not set, and undef on error.
+Check whether the given flag is set on an object. Returns true if set,
+C<0> if not set, and undef on error.
=item flag_clear(FLAG, PRINCIPAL, HOSTNAME [, DATETIME])
Clears FLAG on an object. Returns true on success and false on failure.
-The other arguments are used for logging and history and should indicate the
-user and host from which the change is made and the time of the change.
+The other arguments are used for logging and history and should indicate
+the user and host from which the change is made and the time of the
+change.
=item flag_list()
List the flags set on an object. If no flags are set, returns the empty
-list. On failure, returns an empty list. To distinguish between the empty
-response and an error, the caller should call error() after an empty return.
-It is guaranteed to return undef if there was no error.
+list. On failure, returns an empty list. To distinguish between the
+empty response and an error, the caller should call error() after an empty
+return. It is guaranteed to return undef if there was no error.
=item flag_set(FLAG, PRINCIPAL, HOSTNAME [, DATETIME])
Sets FLAG on an object. Returns true on success and false on failure.
-The other arguments are used for logging and history and should indicate the
-user and host from which the change is made and the time of the change.
+The other arguments are used for logging and history and should indicate
+the user and host from which the change is made and the time of the
+change.
=item get(PRINCIPAL, HOSTNAME [, DATETIME])
@@ -829,9 +866,9 @@ Sets or retrieves the owner of an object as a numeric ACL ID. If no
arguments are given, returns the current owner ACL ID or undef if none is
set. If arguments are given, change the owner to OWNER and return true on
success and false on failure. Pass in the empty string for OWNER to clear
-the owner. The other arguments are used for logging and history and should
-indicate the user and host from which the change is made and the time of the
-change.
+the owner. The other arguments are used for logging and history and
+should indicate the user and host from which the change is made and the
+time of the change.
=item show()
@@ -839,17 +876,17 @@ Returns a formatted text description of the object suitable for human
display, or undef on error. All of the base metadata about the object,
formatted as key: value pairs with the keys aligned in the first 15
characters followed by a space, a colon, and the value. The attr_show()
-method of the object is also called and any formatted output it returns will
-be included. If any ACLs or an owner are set, after this data there is a
-blank line and then the information for each unique ACL, separated by blank
-lines.
+method of the object is also called and any formatted output it returns
+will be included. If any ACLs or an owner are set, after this data there
+is a blank line and then the information for each unique ACL, separated by
+blank lines.
=item store(DATA, PRINCIPAL, HOSTNAME [, DATETIME])
Store user-supplied data into the given object. This may not be supported
-by all backends (for instance, backends that automatically generate the data
-will not support this). The default implementation rejects all store()
-calls with an error message saying that the object is immutable.
+by all backends (for instance, backends that automatically generate the
+data will not support this). The default implementation rejects all
+store() calls with an error message saying that the object is immutable.
=item type()
@@ -867,23 +904,24 @@ provided for subclasses to call to implement some generic actions.
=item log_action (ACTION, PRINCIPAL, HOSTNAME, DATETIME)
Updates the history tables and trace information appropriately for ACTION,
-which should be either C<get> or C<store>. No other changes are made to the
-database, just updates of the history table and trace fields with the
+which should be either C<get> or C<store>. No other changes are made to
+the database, just updates of the history table and trace fields with the
provided data about who performed the action and when.
-This function commits its transaction when complete and therefore should not
-be called inside another transaction. Normally it's called as a separate
-transaction after the data is successfully stored or retrieved.
+This function commits its transaction when complete and therefore should
+not be called inside another transaction. Normally it's called as a
+separate transaction after the data is successfully stored or retrieved.
=item log_set (FIELD, OLD, NEW, PRINCIPAL, HOSTNAME, DATETIME)
-Updates the history tables for the change in a setting value for an object.
-FIELD should be one of C<owner>, C<acl_get>, C<acl_store>, C<acl_show>,
-C<acl_destroy>, C<acl_flags>, C<expires>, C<flags>, or a value starting with
-C<type_data> followed by a space and a type-specific field name. The last
-form is the most common form used by a subclass. OLD is the previous value
-of the field or undef if the field was unset, and NEW is the new value of
-the field or undef if the field should be unset.
+Updates the history tables for the change in a setting value for an
+object. FIELD should be one of C<owner>, C<acl_get>, C<acl_store>,
+C<acl_show>, C<acl_destroy>, C<acl_flags>, C<expires>, C<flags>, or a
+value starting with C<type_data> followed by a space and a type-specific
+field name. The last form is the most common form used by a subclass.
+OLD is the previous value of the field or undef if the field was unset,
+and NEW is the new value of the field or undef if the field should be
+unset.
This function does not commit and does not catch database exceptions. It
should normally be called as part of a larger transaction that implements
@@ -895,8 +933,8 @@ the change in the setting.
wallet-backend(8)
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/Object/File.pm b/perl/Wallet/Object/File.pm
index b4e23f8..c655b44 100644
--- a/perl/Wallet/Object/File.pm
+++ b/perl/Wallet/Object/File.pm
@@ -1,8 +1,7 @@
# Wallet::Object::File -- File object implementation for the wallet.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -25,7 +24,7 @@ use Wallet::Object::Base;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.01';
+$VERSION = '0.02';
##############################################################################
# File naming
@@ -137,6 +136,9 @@ __END__
Wallet::Object::File - File object implementation for wallet
+=for stopwords
+API HOSTNAME DATETIME keytab remctld backend nul Allbery wallet-backend
+
=head1 SYNOPSIS
my @name = qw(file mysql-lsdb)
@@ -164,17 +166,18 @@ set wallet configuration.
=head1 METHODS
This object mostly inherits from Wallet::Object::Base. See the
-documentation for that class for all generic methods. Below are only those
-methods that are overridden or behave specially for this implementation.
+documentation for that class for all generic methods. Below are only
+those methods that are overridden or behave specially for this
+implementation.
=over 4
=item destroy(PRINCIPAL, HOSTNAME [, DATETIME])
Destroys a file object by removing it from the database and deleting the
-corresonding file on the wallet server. Returns true on success and false
-on failure. The caller should call error() to get the error message after
-a failure. PRINCIPAL, HOSTNAME, and DATETIME are stored as history
+corresponding file on the wallet server. Returns true on success and
+false on failure. The caller should call error() to get the error message
+after a failure. PRINCIPAL, HOSTNAME, and DATETIME are stored as history
information. PRINCIPAL should be the user who is destroying the object.
If DATETIME isn't given, the current time is used.
@@ -218,12 +221,11 @@ dashes replaced by C<%> and the hex code of the character.
=head1 LIMITATIONS
-The wallet implementation itself can handle arbitrary file object names
-and arbitrary content. However, due to limitations in the B<remctld>
-server usually used to run B<wallet-backend>, file object names and
-contents containing nul characters (ASCII 0) may not be permitted. The
-file system used for storing file objects may impose a length limitation
-on the file object name.
+The wallet implementation itself can handle arbitrary file object names.
+However, due to limitations in the B<remctld> server usually used to run
+B<wallet-backend>, file object names containing nul characters (ASCII 0)
+may not be permitted. The file system used for storing file objects may
+impose a length limitation on the file object name.
=head1 SEE ALSO
diff --git a/perl/Wallet/Object/Keytab.pm b/perl/Wallet/Object/Keytab.pm
index 8739f89..edb26b3 100644
--- a/perl/Wallet/Object/Keytab.pm
+++ b/perl/Wallet/Object/Keytab.pm
@@ -1,8 +1,8 @@
# Wallet::Object::Keytab -- Keytab object implementation for the wallet.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2009, 2010
+# Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -18,390 +18,14 @@ use vars qw(@ISA $VERSION);
use Wallet::Config ();
use Wallet::Object::Base;
+use Wallet::Kadmin;
@ISA = qw(Wallet::Object::Base);
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.06';
-
-##############################################################################
-# kadmin Interaction
-##############################################################################
-
-# Make sure that principals are well-formed and don't contain characters that
-# will cause us problems when talking to kadmin. Takes a principal and
-# returns true if it's okay, false otherwise. Note that we do not permit
-# realm information here.
-sub valid_principal {
- my ($self, $principal) = @_;
- return scalar ($principal =~ m,^[\w-]+(/[\w_.-]+)?\z,);
-}
-
-# Run a kadmin command and capture the output. Returns the output, either as
-# a list of lines or, in scalar context, as one string. The exit status of
-# kadmin is often worthless.
-sub kadmin {
- my ($self, $command) = @_;
- unless (defined ($Wallet::Config::KEYTAB_PRINCIPAL)
- and defined ($Wallet::Config::KEYTAB_FILE)
- and defined ($Wallet::Config::KEYTAB_REALM)) {
- die "keytab object implementation not configured\n";
- }
- my @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, '-k', '-t',
- $Wallet::Config::KEYTAB_FILE, '-q', $command);
- push (@args, '-s', $Wallet::Config::KEYTAB_HOST)
- if $Wallet::Config::KEYTAB_HOST;
- push (@args, '-r', $Wallet::Config::KEYTAB_REALM)
- if $Wallet::Config::KEYTAB_REALM;
- my $pid = open (KADMIN, '-|');
- if (not defined $pid) {
- die "cannot fork: $!\n";
- } elsif ($pid == 0) {
- # Don't use die here; it will get trapped as an exception. Also be
- # careful about our database handles. (We still lose if there's some
- # other database handle open we don't know about.)
- $self->{dbh}->{InactiveDestroy} = 1;
- unless (open (STDERR, '>&STDOUT')) {
- warn "wallet: cannot dup stdout: $!\n";
- exit 1;
- }
- unless (exec ($Wallet::Config::KEYTAB_KADMIN, @args)) {
- warn "wallet: cannot run $Wallet::Config::KEYTAB_KADMIN: $!\n";
- exit 1;
- }
- }
- local $_;
- my @output;
- while (<KADMIN>) {
- if (/^wallet: cannot /) {
- s/^wallet: //;
- die $_;
- }
- push (@output, $_) unless /Authenticating as principal/;
- }
- close KADMIN;
- return wantarray ? @output : join ('', @output);
-}
-
-# Check whether a given principal already exists in Kerberos. Returns true if
-# so, false otherwise. Throws an exception if kadmin fails.
-sub kadmin_exists {
- my ($self, $principal) = @_;
- return unless $self->valid_principal ($principal);
- if ($Wallet::Config::KEYTAB_REALM) {
- $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
- }
- my $output = $self->kadmin ("getprinc $principal");
- if ($output =~ /^get_principal: /) {
- return;
- } else {
- return 1;
- }
-}
-
-# Create a principal in Kerberos. Since this is only called by create, it
-# throws an exception on failure rather than setting the error and returning
-# undef.
-sub kadmin_addprinc {
- my ($self, $principal) = @_;
- unless ($self->valid_principal ($principal)) {
- die "invalid principal name $principal\n";
- }
- return 1 if $self->kadmin_exists ($principal);
- if ($Wallet::Config::KEYTAB_REALM) {
- $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
- }
- my $flags = $Wallet::Config::KEYTAB_FLAGS || '';
- my $output = $self->kadmin ("addprinc -randkey $flags $principal");
- if ($output =~ /^add_principal: (.*)/m) {
- die "error adding principal $principal: $1\n";
- }
- return 1;
-}
-
-# Create a keytab from a principal. Takes the principal, the file, and
-# optionally a list of encryption types to which to limit the keytab. Return
-# true if successful, false otherwise. If the keytab creation fails, sets the
-# error.
-sub kadmin_ktadd {
- my ($self, $principal, $file, @enctypes) = @_;
- unless ($self->valid_principal ($principal)) {
- $self->error ("invalid principal name: $principal");
- return;
- }
- if ($Wallet::Config::KEYTAB_REALM) {
- $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
- }
- my $command = "ktadd -q -k $file";
- if (@enctypes) {
- @enctypes = map { /:/ ? $_ : "$_:normal" } @enctypes;
- $command .= ' -e "' . join (' ', @enctypes) . '"';
- }
- my $output = eval { $self->kadmin ("$command $principal") };
- if ($@) {
- $self->error ($@);
- return;
- } elsif ($output =~ /^(?:kadmin|ktadd): (.*)/m) {
- $self->error ("error creating keytab for $principal: $1");
- return;
- }
- return 1;
-}
-
-# Delete a principal from Kerberos. Return true if successful, false
-# otherwise. If the deletion fails, sets the error. If the principal doesn't
-# exist, return success; we're bringing reality in line with our expectations.
-sub kadmin_delprinc {
- my ($self, $principal) = @_;
- unless ($self->valid_principal ($principal)) {
- $self->error ("invalid principal name: $principal");
- return;
- }
- my $exists = eval { $self->kadmin_exists ($principal) };
- if ($@) {
- $self->error ($@);
- return;
- } elsif (not $exists) {
- return 1;
- }
- if ($Wallet::Config::KEYTAB_REALM) {
- $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
- }
- my $output = eval { $self->kadmin ("delprinc -force $principal") };
- if ($@) {
- $self->error ($@);
- return;
- } elsif ($output =~ /^delete_principal: (.*)/m) {
- $self->error ("error deleting $principal: $1");
- return;
- }
- return 1;
-}
-
-##############################################################################
-# AFS kaserver synchronization
-##############################################################################
-
-# Given a Kerberos v5 principal name, convert it to a Kerberos v4 principal
-# name. Returns undef if it can't convert the name for some reason (right
-# now, only if the principal has more than two parts). Note that this mapping
-# does not guarantee a unique result; multiple hosts in different domains can
-# be mapped to the same Kerberos v4 principal name using this function.
-sub kaserver_name {
- my ($self, $k5) = @_;
- my %host = map { $_ => 1 } qw(host ident imap pop smtp);
- $k5 =~ s/\@.*//;
- my @parts = split ('/', $k5);
- if (@parts > 2) {
- return;
- } elsif (@parts == 2 and $host{$parts[0]}) {
- $parts[1] =~ s/\..*//;
- $parts[0] = 'rcmd' if $parts[0] eq 'host';
- }
- my $k4 = join ('.', @parts);
- if ($Wallet::Config::KEYTAB_AFS_REALM) {
- $k4 .= '@' . $Wallet::Config::KEYTAB_AFS_REALM;
- }
- return $k4;
-}
-
-# Run kasetkey with the given arguments. Returns true on success and false on
-# failure. On failure, sets the internal error to the error from kasetkey.
-sub kaserver_kasetkey {
- my ($self, @args) = @_;
- my $admin = $Wallet::Config::KEYTAB_AFS_ADMIN;
- my $admin_srvtab = $Wallet::Config::KEYTAB_AFS_SRVTAB;
- my $kasetkey = $Wallet::Config::KEYTAB_AFS_KASETKEY;
- unless ($kasetkey and $admin and $admin_srvtab) {
- $self->error ('kaserver synchronization not configured');
- return;
- }
- my $pid = open (KASETKEY, '-|');
- if (not defined $pid) {
- $self->error ("cannot fork: $!");
- return;
- } elsif ($pid == 0) {
- # Don't use die here; it will get trapped as an exception. Also be
- # careful about our database handles. (We still lose if there's some
- # other database handle open we don't know about.)
- $self->{dbh}->{InactiveDestroy} = 1;
- unless (open (STDERR, '>&STDOUT')) {
- warn "cannot redirect stderr: $!\n";
- exit 1;
- }
- unless (exec ($kasetkey, '-k', $admin_srvtab, '-a', $admin, @args)) {
- warn "cannot exec $kasetkey: $!\n";
- exit 1;
- }
- } else {
- local $/;
- my $output = <KASETKEY>;
- close KASETKEY;
- if ($? != 0) {
- $output =~ s/\s+\z//;
- $output =~ s/\n/, /g;
- $output = ': ' . $output if $output;
- $self->error ("cannot synchronize key with kaserver$output");
- return;
- }
- }
- return 1;
-}
-
-# Given a keytab file name, the Kerberos v5 principal that's stored in that
-# keytab, a srvtab file name, and the corresponding Kerberos v4 principal,
-# write out a srvtab file containing the DES key in that keytab. Fails if
-# there is no DES key in the keytab.
-sub kaserver_srvtab {
- my ($self, $keytab, $k5, $srvtab, $k4) = @_;
-
- # Gah. Someday I will write Perl bindings for Kerberos that are less
- # broken.
- eval { require Authen::Krb5 };
- if ($@) {
- $self->error ("kaserver synchronization support not available: $@");
- return;
- }
- eval { Authen::Krb5::init_context() };
- if ($@ and not $@ =~ /^Authen::Krb5 already initialized/) {
- $self->error ('Kerberos initialization failed');
- return;
- }
- undef $@;
-
- # Do the interface dance. We call kt_read_service_key with 0 for the kvno
- # to get any kvno, which works with MIT Kerberos at least. Assume a DES
- # enctype of 1. This code won't work with any enctype other than
- # des-cbc-crc.
- my $princ = Authen::Krb5::parse_name ($k5);
- unless (defined $princ) {
- my $error = Authen::Krb5::error();
- $self->error ("cannot parse $k5: $error");
- return;
- }
- my $key = Authen::Krb5::kt_read_service_key ($keytab, $princ, 0, 1);
- unless (defined $key) {
- my $error = Authen::Krb5::error();
- $self->error ("cannot find des-cbc-crc key in $keytab: $error");
- return;
- }
- unless (open (SRVTAB, '>', $srvtab)) {
- $self->error ("cannot create $srvtab: $!");
- return;
- }
-
- # srvtab format is nul-terminated name, nul-terminated instance,
- # nul-terminated realm, single character kvno (which we always set to 0),
- # and DES keyblock.
- my ($principal, $realm) = split ('@', $k4);
- $realm ||= '';
- my ($name, $inst) = split (/\./, $principal, 2);
- $inst ||= '';
- my $data = join ("\0", $name, $inst, $realm);
- $data .= "\0\0" . $key->contents;
- print SRVTAB $data;
- unless (close SRVTAB) {
- unlink $srvtab;
- $self->error ("cannot write to $srvtab: $!");
- return;
- }
- return 1;
-}
-
-# Given a principal name and a path to the keytab, synchronizes the key with a
-# principal in an AFS kaserver. Returns true on success and false on failure.
-# On failure, sets the internal error.
-sub kaserver_sync {
- my ($self, $principal, $keytab) = @_;
- if ($Wallet::Config::KEYTAB_REALM) {
- $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
- }
- my $k4 = $self->kaserver_name ($principal);
- if (not defined $k4) {
- $self->error ("cannot convert $principal to Kerberos v4");
- return;
- }
- my $srvtab = $Wallet::Config::KEYTAB_TMP . "/srvtab.$$";
- unless ($self->kaserver_srvtab ($keytab, $principal, $srvtab, $k4)) {
- return;
- }
- unless ($self->kaserver_kasetkey ('-c', $srvtab, '-s', $k4)) {
- unlink $srvtab;
- return;
- }
- unlink $srvtab;
- return 1;
-}
-
-# Given a principal name, destroy the corresponding principal in the AFS
-# kaserver. Returns true on success and false on failure, setting the object
-# error if it fails.
-sub kaserver_destroy {
- my ($self, $principal) = @_;
- my $k4 = $self->kaserver_name ($principal);
- if (not defined $k4) {
- $self->error ("cannot convert $principal to Kerberos v4");
- return;
- }
- return $self->kaserver_kasetkey ('-D', $k4);
-}
-
-# Set the kaserver sync attribute. Called by attr(). Returns true on success
-# and false on failure, setting the object error if it fails.
-sub kaserver_set {
- my ($self, $user, $host, $time) = @_;
- $time ||= time;
- my @trace = ($user, $host, $time);
- my $name = $self->{name};
- eval {
- my $sql = "select ks_name from keytab_sync where ks_name = ? and
- ks_target = 'kaserver'";
- my $result = $self->{dbh}->selectrow_array ($sql, undef, $name);
- if ($result) {
- die "kaserver synchronization already set\n";
- }
- $sql = "insert into keytab_sync (ks_name, ks_target)
- values (?, 'kaserver')";
- $self->{dbh}->do ($sql, undef, $name);
- $self->log_set ('type_data sync', undef, 'kaserver', @trace);
- $self->{dbh}->commit;
- };
- if ($@) {
- $self->error ($@);
- $self->{dbh}->rollback;
- return;
- }
- return 1;
-}
-
-# Clear the kaserver sync attribute. Called by attr(). Returns true on
-# success and false on failure, setting the object error if it fails.
-sub kaserver_clear {
- my ($self, $user, $host, $time) = @_;
- $time ||= time;
- my @trace = ($user, $host, $time);
- my $name = $self->{name};
- eval {
- my $sql = "select ks_name from keytab_sync where ks_name = ? and
- ks_target = 'kaserver'";
- my $result = $self->{dbh}->selectrow_array ($sql, undef, $name);
- unless ($result) {
- die "kaserver synchronization not set\n";
- }
- $sql = 'delete from keytab_sync where ks_name = ?';
- $self->{dbh}->do ($sql, undef, $name);
- $self->log_set ('type_data sync', 'kaserver', undef, @trace);
- $self->{dbh}->commit;
- };
- if ($@) {
- $self->error ($@);
- $self->{dbh}->rollback;
- return;
- }
- return 1;
-}
+$VERSION = '0.08';
##############################################################################
# Enctype restriction
@@ -487,55 +111,86 @@ sub enctypes_list {
}
##############################################################################
-# Keytab retrieval
+# Synchronization
##############################################################################
-# Retrieve an existing keytab from the KDC via a remctl call. The KDC needs
-# to be running the keytab-backend script and support the keytab retrieve
-# remctl command. In addition, the user must have configured us with the path
-# to a ticket cache and the host to which to connect with remctl. Returns the
-# keytab on success and undef on failure.
-sub keytab_retrieve {
- my ($self, $keytab) = @_;
- my $host = $Wallet::Config::KEYTAB_REMCTL_HOST;
- unless ($host and $Wallet::Config::KEYTAB_REMCTL_CACHE) {
- $self->error ('keytab unchanging support not configured');
+# Set a synchronization target or clear the targets if $targets is an
+# empty list. Returns true on success and false on failure.
+#
+# Currently, no synchronization targets are supported, but we preserve the
+# ability to clear synchronization and the basic structure of the code so
+# that they can be added later.
+sub sync_set {
+ my ($self, $targets, $user, $host, $time) = @_;
+ $time ||= time;
+ my @trace = ($user, $host, $time);
+ if (@$targets > 1) {
+ $self->error ('only one synchronization target supported');
return;
- }
- eval { require Net::Remctl };
- if ($@) {
- $self->error ("keytab unchanging support not available: $@");
+ } elsif (@$targets) {
+ my $target = $targets->[0];
+ $self->error ("unsupported synchronization target $target");
return;
+ } else {
+ eval {
+ my $sql = 'select ks_target from keytab_sync where ks_name = ?';
+ my $dbh = $self->{dbh};
+ my $name = $self->{name};
+ my ($result) = $dbh->selectrow_array ($sql, undef, $name);
+ if ($result) {
+ my $sql = 'delete from keytab_sync where ks_name = ?';
+ $self->{dbh}->do ($sql, undef, $name);
+ $self->log_set ('type_data sync', $result, undef, @trace);
+ }
+ $self->{dbh}->commit;
+ };
+ if ($@) {
+ $self->error ($@);
+ $self->{dbh}->rollback;
+ return;
+ }
}
- if ($Wallet::Config::KEYTAB_REALM) {
- $keytab .= '@' . $Wallet::Config::KEYTAB_REALM;
- }
- local $ENV{KRB5CCNAME} = $Wallet::Config::KEYTAB_REMCTL_CACHE;
- my $port = $Wallet::Config::KEYTAB_REMCTL_PORT || 0;
- my $principal = $Wallet::Config::KEYTAB_REMCTL_PRINCIPAL || '';
- my @command = ('keytab', 'retrieve', $keytab);
- my $result = Net::Remctl::remctl ($host, $port, $principal, @command);
- if ($result->error) {
- $self->error ("cannot retrieve keytab for $keytab: ", $result->error);
- return;
- } elsif ($result->status != 0) {
- my $error = $result->stderr;
- $error =~ s/\s+$//;
- $error =~ s/\n/ /g;
- $self->error ("cannot retrieve keytab for $keytab: $error");
+ return 1;
+}
+
+# Return a list of the current synchronization targets. Returns the empty
+# list on failure or on an empty list of enctype restrictions, but sets
+# the object error on failure so the caller should use that to determine
+# success.
+sub sync_list {
+ my ($self) = @_;
+ my @targets;
+ eval {
+ my $sql = 'select ks_target from keytab_sync where ks_name = ?
+ order by ks_target';
+ my $sth = $self->{dbh}->prepare ($sql);
+ $sth->execute ($self->{name});
+ my $target;
+ while (defined ($target = $sth->fetchrow_array)) {
+ push (@targets, $target);
+ }
+ $self->{dbh}->commit;
+ };
+ if ($@) {
+ $self->error ($@);
+ $self->{dbh}->rollback;
return;
- } else {
- return $result->stdout;
}
+ return @targets;
}
##############################################################################
# Core methods
##############################################################################
-# Override attr to support setting the enctypes and sync attributes.
+# Override attr to support setting the enctypes and sync attributes. Note
+# that the sync attribute has no supported targets at present and hence will
+# always return an error, but the code is still here so that it doesn't have
+# to be rewritten once a new sync target is added.
sub attr {
my ($self, $attribute, $values, $user, $host, $time) = @_;
+ $time ||= time;
+ my @trace = ($user, $host, $time);
my %known = map { $_ => 1 } qw(enctypes sync);
undef $self->{error};
unless ($known{$attribute}) {
@@ -544,43 +199,15 @@ sub attr {
}
if ($values) {
if ($attribute eq 'enctypes') {
- $self->enctypes_set ($values, $user, $host, $time);
+ return $self->enctypes_set ($values, $user, $host, $time);
} elsif ($attribute eq 'sync') {
- if (@$values > 1) {
- $self->error ('only one synchronization target supported');
- return;
- } elsif (@$values and $values->[0] ne 'kaserver') {
- my $target = $values->[0];
- $self->error ("unsupported synchronization target $target");
- return;
- } elsif (@$values) {
- return $self->kaserver_set ($user, $host, $time);
- } else {
- return $self->kaserver_clear ($user, $host, $time);
- }
+ return $self->sync_set ($values, $user, $host, $time);
}
} else {
if ($attribute eq 'enctypes') {
return $self->enctypes_list;
} elsif ($attribute eq 'sync') {
- my @targets;
- eval {
- my $sql = 'select ks_target from keytab_sync where ks_name = ?
- order by ks_target';
- my $sth = $self->{dbh}->prepare ($sql);
- $sth->execute ($self->{name});
- my $target;
- while (defined ($target = $sth->fetchrow_array)) {
- push (@targets, $target);
- }
- $self->{dbh}->commit;
- };
- if ($@) {
- $self->error ($@);
- $self->{dbh}->rollback;
- return;
- }
- return @targets;
+ return $self->sync_list;
}
}
}
@@ -608,16 +235,53 @@ sub attr_show {
return $output;
}
+# Override new to start by creating a handle for the kadmin module we're
+# using.
+sub new {
+ my ($class, $type, $name, $dbh) = @_;
+ my $self = {
+ dbh => $dbh,
+ kadmin => undef,
+ };
+ bless $self, $class;
+ my $kadmin = Wallet::Kadmin->new ();
+ $self->{kadmin} = $kadmin;
+
+ # Set a callback for things to do after a fork, specifically for the MIT
+ # kadmin module which forks to kadmin.
+ my $callback = sub { $self->{dbh}->{InactiveDestroy} = 1 };
+ $kadmin->fork_callback ($callback);
+
+ $self = $class->SUPER::new ($type, $name, $dbh);
+ $self->{kadmin} = $kadmin;
+ return $self;
+}
+
# Override create to start by creating the principal in Kerberos and only
# create the entry in the database if that succeeds. Error handling isn't
# great here since we don't have a way to communicate the error back to the
# caller.
sub create {
my ($class, $type, $name, $dbh, $creator, $host, $time) = @_;
- my $self = { dbh => $dbh };
+ my $self = {
+ dbh => $dbh,
+ kadmin => undef,
+ };
bless $self, $class;
- $self->kadmin_addprinc ($name);
- return $class->SUPER::create ($type, $name, $dbh, $creator, $host, $time);
+ my $kadmin = Wallet::Kadmin->new ();
+ $self->{kadmin} = $kadmin;
+
+ # Set a callback for things to do after a fork, specifically for the MIT
+ # kadmin module which forks to kadmin.
+ my $callback = sub { $self->{dbh}->{InactiveDestroy} = 1 };
+ $kadmin->fork_callback ($callback);
+
+ if (not $kadmin->create ($name)) {
+ die $kadmin->error, "\n";
+ }
+ $self = $class->SUPER::create ($type, $name, $dbh, $creator, $host, $time);
+ $self->{kadmin} = $kadmin;
+ return $self;
}
# Override destroy to delete the principal out of Kerberos as well.
@@ -628,12 +292,6 @@ sub destroy {
$self->error ("cannot destroy $id: object is locked");
return;
}
- my @sync = $self->attr ('sync');
- if (grep { $_ eq 'kaserver' } @sync) {
- unless ($self->kaserver_destroy ($self->{name})) {
- return;
- }
- }
eval {
my $sql = 'delete from keytab_sync where ks_name = ?';
$self->{dbh}->do ($sql, undef, $self->{name});
@@ -646,7 +304,11 @@ sub destroy {
$self->{dbh}->rollback;
return;
}
- return if not $self->kadmin_delprinc ($self->{name});
+ my $kadmin = $self->{kadmin};
+ if (not $kadmin->destroy ($self->{name})) {
+ $self->error ($kadmin->error);
+ return;
+ }
return $self->SUPER::destroy ($user, $host, $time);
}
@@ -660,49 +322,20 @@ sub get {
$self->error ("cannot get $id: object is locked");
return;
}
+ my $kadmin = $self->{kadmin};
+ my $result;
if ($self->flag_check ('unchanging')) {
- my $result = $self->keytab_retrieve ($self->{name});
- if (defined $result) {
- $self->log_action ('get', $user, $host, $time);
- }
- return $result;
- }
- unless (defined ($Wallet::Config::KEYTAB_TMP)) {
- $self->error ('KEYTAB_TMP configuration variable not set');
- return;
- }
- my $file = $Wallet::Config::KEYTAB_TMP . "/keytab.$$";
- unlink $file;
- my @enctypes = $self->attr ('enctypes');
- return if not $self->kadmin_ktadd ($self->{name}, $file, @enctypes);
- local *KEYTAB;
- unless (open (KEYTAB, '<', $file)) {
- my $princ = $self->{name};
- $self->error ("error opening keytab for principal $princ: $!");
- return;
- }
- local $/;
- undef $!;
- my $data = <KEYTAB>;
- if ($!) {
- my $princ = $self->{name};
- $self->error ("error reading keytab for principal $princ: $!");
- unlink $file;
- return;
+ $result = $kadmin->keytab ($self->{name});
+ } else {
+ my @enctypes = $self->attr ('enctypes');
+ $result = $kadmin->keytab_rekey ($self->{name}, @enctypes);
}
- close KEYTAB;
- my @sync = $self->attr ('sync');
- if (grep { $_ eq 'kaserver' } @sync) {
- unless ($self->kaserver_sync ($self->{name}, $file)) {
- unlink $file;
- return;
- }
- } elsif ($Wallet::Config::KEYTAB_AFS_DESTROY) {
- $self->kaserver_destroy ($self->{name});
+ if (defined $result) {
+ $self->log_action ('get', $user, $host, $time);
+ } else {
+ $self->error ($kadmin->error);
}
- unlink $file;
- $self->log_action ('get', $user, $host, $time);
- return $data;
+ return $result;
}
1;
@@ -712,6 +345,10 @@ __END__
# Documentation
##############################################################################
+=for stopwords
+keytab API KDC keytabs HOSTNAME DATETIME enctypes enctype DBH metadata
+unmanaged kadmin Allbery
+
=head1 NAME
Wallet::Object::Keytab - Keytab object implementation for wallet
@@ -726,17 +363,17 @@ Wallet::Object::Keytab - Keytab object implementation for wallet
=head1 DESCRIPTION
-Wallet::Object::Keytab is a representation of Kerberos keytab objects in the
-wallet. It implements the wallet object API and provides the necessary
-glue to create principals in a Kerberos KDC, create and return keytabs for
-those principals, and delete them out of Kerberos when the wallet object is
-destroyed.
+Wallet::Object::Keytab is a representation of Kerberos keytab objects in
+the wallet. It implements the wallet object API and provides the
+necessary glue to create principals in a Kerberos KDC, create and return
+keytabs for those principals, and delete them out of Kerberos when the
+wallet object is destroyed.
A keytab is an on-disk store for the key or keys for a Kerberos principal.
-Keytabs are used by services to verify incoming authentication from clients
-or by automated processes that need to authenticate to Kerberos. To create
-a keytab, the principal has to be created in Kerberos and then a keytab is
-generated and stored in a file on disk.
+Keytabs are used by services to verify incoming authentication from
+clients or by automated processes that need to authenticate to Kerberos.
+To create a keytab, the principal has to be created in Kerberos and then a
+keytab is generated and stored in a file on disk.
This implementation generates a new random key (and hence invalidates all
existing keytabs) each time the keytab is retrieved with the get() method.
@@ -748,14 +385,15 @@ information about how to set wallet configuration.
=head1 METHODS
This object mostly inherits from Wallet::Object::Base. See the
-documentation for that class for all generic methods. Below are only those
-methods that are overridden or behave specially for this implementation.
+documentation for that class for all generic methods. Below are only
+those methods that are overridden or behave specially for this
+implementation.
=over 4
=item attr(ATTRIBUTE [, VALUES, PRINCIPAL, HOSTNAME [, DATETIME]])
-Sets or retrieves a given object attribute. The following attributes are
+Sets or retrieves a given object attribute. The following attribute is
supported:
=over 4
@@ -764,15 +402,15 @@ supported:
Restricts the generated keytab to a specific set of encryption types. The
values of this attribute must be enctype strings recognized by Kerberos
-(strings like C<aes256-cts> or C<des-cbc-crc>). Encryption types must also
-be present in the list of supported enctypes stored in the database database
-or the attr() method will reject them. Note that the salt should not be
-included; since the salt is irrelevant for keytab keys, it will always be
-set to C<normal> by the wallet.
+(strings like C<aes256-cts-hmac-sha1-96> or C<des-cbc-crc>). Encryption
+types must also be present in the list of supported enctypes stored in the
+database database or the attr() method will reject them. Note that the
+salt should not be included; since the salt is irrelevant for keytab keys,
+it will always be set to the default by the wallet.
-If this attribute is set, the specified enctype list will be passed to
-ktadd when get() is called for that keytab. If it is not set, the default
-set in the KDC will be used.
+If this attribute is set, the principal will be restricted to that
+specific enctype list when get() is called for that keytab. If it is not
+set, the default set in the KDC will be used.
This attribute is ignored if the C<unchanging> flag is set on a keytab.
Keytabs retrieved with C<unchanging> set will contain all keys present in
@@ -781,33 +419,21 @@ enctypes than those requested by this attribute.
=item sync
-Sets the external systems to which the key of a given principal is
-synchronized. The only supported value for this attribute is C<kaserver>,
-which says to synchronize the key with an AFS Kerberos v4 kaserver.
-
-If this attribute is set on a keytab, whenever get() is called for that
-keytab, the new DES key will be extracted from that keytab and set in the
-configured AFS kaserver. The Kerberos v4 principal name will be the same as
-the Kerberos v5 principal name except that the components are separated by
-C<.> instead of C</>; the second component is truncated after the first C<.>
-if the first component is one of C<host>, C<ident>, C<imap>, C<pop>, or
-C<smtp>; and the first component is C<rcmd> if the Kerberos v5 principal
-component is C<host>. The principal name must not contain more than two
-components.
-
-If this attribute is set, calling destroy() will also destroy the principal
-from the AFS kaserver, with a principal mapping determined as above.
+This attribute is intended to set a list of external systems with which
+data about this keytab is synchronized, but there are no supported targets
+currently. However, there is support for clearing this attribute or
+returning its current value.
=back
If no other arguments besides ATTRIBUTE are given, returns the values of
that attribute, if any, as a list. On error, returns the empty list. To
-distinguish between an error and an empty return, call error() afterwards.
+distinguish between an error and an empty return, call error() afterward.
It is guaranteed to return undef unless there was an error.
If other arguments are given, sets the given ATTRIBUTE values to VALUES,
-which must be a reference to an array (even if only one value is being set).
-Pass a reference to an empty array to clear the attribute values.
+which must be a reference to an array (even if only one value is being
+set). Pass a reference to an empty array to clear the attribute values.
PRINCIPAL, HOSTNAME, and DATETIME are stored as history information.
PRINCIPAL should be the user who is destroying the object. If DATETIME
isn't given, the current time is used.
@@ -816,20 +442,20 @@ isn't given, the current time is used.
This is a class method and should be called on the Wallet::Object::Keytab
class. It creates a new object with the given TYPE and NAME (TYPE is
-normally C<keytab> and must be for the rest of the wallet system to use the
-right class, but this module doesn't check for ease of subclassing), using
-DBH as the handle to the wallet metadata database. PRINCIPAL, HOSTNAME, and
-DATETIME are stored as history information. PRINCIPAL should be the user
-who is creating the object. If DATETIME isn't given, the current time is
-used.
+normally C<keytab> and must be for the rest of the wallet system to use
+the right class, but this module doesn't check for ease of subclassing),
+using DBH as the handle to the wallet metadata database. PRINCIPAL,
+HOSTNAME, and DATETIME are stored as history information. PRINCIPAL
+should be the user who is creating the object. If DATETIME isn't given,
+the current time is used.
When a new keytab object is created, the Kerberos principal designated by
NAME is also created in the Kerberos realm determined from the wallet
-configuration. If the principal already exists, create() still succeeds (so
-that a previously unmanaged principal can be imported into the wallet).
-Otherwise, if the Kerberos principal could not be created, create() fails.
-The principal is created with the C<-randkey> option to randomize its keys.
-NAME must not contain the realm; instead, the KEYTAB_REALM configuration
+configuration. If the principal already exists, create() still succeeds
+(so that a previously unmanaged principal can be imported into the
+wallet). Otherwise, if the Kerberos principal could not be created,
+create() fails. The principal is created with the randomized keys. NAME
+must not contain the realm; instead, the KEYTAB_REALM configuration
variable should be set. See Wallet::Config(3) for more information.
If create() fails, it throws an exception.
@@ -847,18 +473,14 @@ destroying the object. If DATETIME isn't given, the current time is used.
=item get(PRINCIPAL, HOSTNAME [, DATETIME])
-Retrieves a keytab for this object and returns the keytab data or undef
-on error. The caller should call error() to get the error message if
-get() returns undef. The keytab is created with C<ktadd>, invalidating
-any existing keytabs for that principal, unless the unchanging flag is set
-on the object. PRINCIPAL, HOSTNAME, and DATETIME are stored as history
-information. PRINCIPAL should be the user who is downloading the keytab.
-If DATETIME isn't given, the current time is used.
-
-If the configuration variable $KEYTAB_AFS_DESTROY is set and the C<sync>
-attribute is not set to C<kaserver>, calling get() on a keytab object will
-cause the corresponding Kerberos v4 principal to be destroyed. This
-variable is not set by default.
+Retrieves a keytab for this object and returns the keytab data or undef on
+error. The caller should call error() to get the error message if get()
+returns undef. The keytab is created with new randomized keys,
+invalidating any existing keytabs for that principal, unless the
+unchanging flag is set on the object. PRINCIPAL, HOSTNAME, and DATETIME
+are stored as history information. PRINCIPAL should be the user who is
+downloading the keytab. If DATETIME isn't given, the current time is
+used.
=back
@@ -868,30 +490,24 @@ variable is not set by default.
=item KEYTAB_TMP/keytab.<pid>
-The keytab is created in this file using C<ktadd> and then read into memory.
-KEYTAB_TMP is set in the wallet configuration, and <pid> is the process ID
-of the current process. The file is unlinked after being read.
+The keytab is created in this file and then read into memory. KEYTAB_TMP
+is set in the wallet configuration, and <pid> is the process ID of the
+current process. The file is unlinked after being read.
=back
=head1 LIMITATIONS
-Currently, this implementation only supports MIT Kerberos and needs
-modifications to support Heimdal. It calls an external B<kadmin> program
-rather than using a native Perl module and therefore requires B<kadmin> be
-installed and parses its output. It may miss some error conditions if the
-output of B<kadmin> ever changes.
-
Only one Kerberos realm is supported for a given wallet implementation and
-all keytab objects stored must be in that realm. Keytab names in the wallet
-database do not have realm information.
+all keytab objects stored must be in that realm. Keytab names in the
+wallet database do not have realm information.
=head1 SEE ALSO
kadmin(8), Wallet::Config(3), Wallet::Object::Base(3), wallet-backend(8)
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/Report.pm b/perl/Wallet/Report.pm
new file mode 100644
index 0000000..7cd8653
--- /dev/null
+++ b/perl/Wallet/Report.pm
@@ -0,0 +1,425 @@
+# Wallet::Report -- Wallet system reporting interface.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+##############################################################################
+# Modules and declarations
+##############################################################################
+
+package Wallet::Report;
+require 5.006;
+
+use strict;
+use vars qw($VERSION);
+
+use Wallet::Database;
+
+# This version should be increased on any code change to this module. Always
+# use two digits for the minor version with a leading zero if necessary so
+# that it will sort properly.
+$VERSION = '0.01';
+
+##############################################################################
+# Constructor, destructor, and accessors
+##############################################################################
+
+# Create a new wallet report object. Opens a connection to the database that
+# will be used for all of the wallet configuration information. Throw an
+# exception if anything goes wrong.
+sub new {
+ my ($class) = @_;
+ my $dbh = Wallet::Database->connect;
+ my $self = { dbh => $dbh };
+ bless ($self, $class);
+ return $self;
+}
+
+# Returns the database handle (used mostly for testing).
+sub dbh {
+ my ($self) = @_;
+ return $self->{dbh};
+}
+
+# Set or return the error stashed in the object.
+sub error {
+ my ($self, @error) = @_;
+ if (@error) {
+ my $error = join ('', @error);
+ chomp $error;
+ 1 while ($error =~ s/ at \S+ line \d+\.?\z//);
+ $self->{error} = $error;
+ }
+ return $self->{error};
+}
+
+# Disconnect the database handle on object destruction to avoid warnings.
+sub DESTROY {
+ my ($self) = @_;
+ $self->{dbh}->disconnect unless $self->{dbh}->{InactiveDestroy};
+}
+
+##############################################################################
+# Object reports
+##############################################################################
+
+# Return the SQL statement to find every object in the database.
+sub objects_all {
+ my ($self) = @_;
+ my $sql = 'select ob_type, ob_name from objects order by ob_type,
+ ob_name';
+ return $sql;
+}
+
+# Return the SQL statement and the search field required to find all objects
+# matching a specific type.
+sub objects_type {
+ my ($self, $type) = @_;
+ my $sql = 'select ob_type, ob_name from objects where ob_type=? order
+ by ob_type, ob_name';
+ return ($sql, $type);
+}
+
+# Return the SQL statement and search field required to find all objects owned
+# by a given ACL. If the requested owner is null, we ignore this and do a
+# different search for IS NULL. If the requested owner does not actually
+# match any ACLs, set an error and return undef.
+sub objects_owner {
+ my ($self, $owner) = @_;
+ my ($sth);
+ if (lc ($owner) eq 'null') {
+ my $sql = 'select ob_type, ob_name from objects where ob_owner is null
+ order by objects.ob_type, objects.ob_name';
+ return ($sql);
+ } else {
+ my $acl = eval { Wallet::ACL->new ($owner, $self->{dbh}) };
+ return unless $acl;
+ my $sql = 'select ob_type, ob_name from objects where ob_owner = ?
+ order by objects.ob_type, objects.ob_name';
+ return ($sql, $acl->id);
+ }
+}
+
+# Return the SQL statement and search field required to find all objects that
+# have a specific flag set.
+sub objects_flag {
+ my ($self, $flag) = @_;
+ my $sql = 'select ob_type, ob_name from objects left join flags on
+ (objects.ob_type = flags.fl_type and objects.ob_name = flags.fl_name)
+ where flags.fl_flag = ? order by objects.ob_type, objects.ob_name';
+ return ($sql, $flag);
+}
+
+# Return the SQL statement and search field required to find all objects that
+# a given ACL has any permissions on. This expands from objects_owner in that
+# it will also match any records that have the ACL set for get, store, show,
+# destroy, or flags. If the requested owner does not actually match any ACLs,
+# set an error and return the empty string.
+sub objects_acl {
+ my ($self, $search) = @_;
+ my $acl = eval { Wallet::ACL->new ($search, $self->{dbh}) };
+ return unless $acl;
+ my $sql = 'select ob_type, ob_name from objects where ob_owner = ? or
+ ob_acl_get = ? or ob_acl_store = ? or ob_acl_show = ? or
+ ob_acl_destroy = ? or ob_acl_flags = ? order by objects.ob_type,
+ objects.ob_name';
+ return ($sql, ($acl->id) x 6);
+}
+
+# Returns a list of all objects stored in the wallet database in the form of
+# type and name pairs. On error and for an empty database, the empty list
+# will be returned. To distinguish between an empty list and an error, call
+# error(), which will return undef if there was no error. Farms out specific
+# statement to another subroutine for specific search types, but each case
+# should return ob_type and ob_name in that order.
+sub objects {
+ my ($self, $type, @args) = @_;
+ undef $self->{error};
+
+ # Find the SQL statement and the arguments to use.
+ my $sql = '';
+ my @search = ();
+ if (!defined $type || $type eq '') {
+ ($sql) = $self->objects_all;
+ } else {
+ if (@args != 1) {
+ $self->error ("object searches require one argument to search");
+ } elsif ($type eq 'type') {
+ ($sql, @search) = $self->objects_type (@args);
+ } elsif ($type eq 'owner') {
+ ($sql, @search) = $self->objects_owner (@args);
+ } elsif ($type eq 'flag') {
+ ($sql, @search) = $self->objects_flag (@args);
+ } elsif ($type eq 'acl') {
+ ($sql, @search) = $self->objects_acl (@args);
+ } else {
+ $self->error ("do not know search type: $type");
+ }
+ return unless $sql;
+ }
+
+ # Do the search.
+ my @objects;
+ eval {
+ my $sth = $self->{dbh}->prepare ($sql);
+ $sth->execute (@search);
+ my $object;
+ while (defined ($object = $sth->fetchrow_arrayref)) {
+ push (@objects, [ @$object ]);
+ }
+ $self->{dbh}->commit;
+ };
+ if ($@) {
+ $self->error ("cannot list objects: $@");
+ $self->{dbh}->rollback;
+ return;
+ }
+ return @objects;
+}
+
+##############################################################################
+# ACL reports
+##############################################################################
+
+# Returns the SQL statement required to find and return all ACLs in the
+# database.
+sub acls_all {
+ my ($self) = @_;
+ my $sql = 'select ac_id, ac_name from acls order by ac_id';
+ return ($sql);
+}
+
+# Returns the SQL statement required to find all empty ACLs in the database.
+sub acls_empty {
+ my ($self) = @_;
+ my $sql = 'select ac_id, ac_name from acls left join acl_entries
+ on (acls.ac_id = acl_entries.ae_id) where ae_id is null';
+ return ($sql);
+}
+
+# Returns the SQL statement and the field required to find ACLs containing the
+# specified entry. The identifier is automatically surrounded by wildcards to
+# do a substring search.
+sub acls_entry {
+ my ($self, $type, $identifier) = @_;
+ my $sql = 'select distinct ac_id, ac_name from acl_entries left join acls
+ on (ae_id = ac_id) where ae_scheme = ? and ae_identifier like ? order
+ by ac_id';
+ return ($sql, $type, '%' . $identifier . '%');
+}
+
+# Returns a list of all ACLs stored in the wallet database as a list of pairs
+# of ACL IDs and ACL names, possibly limited by some criteria. On error and
+# for an empty database, the empty list will be returned. To distinguish
+# between an empty list and an error, call error(), which will return undef if
+# there was no error.
+sub acls {
+ my ($self, $type, @args) = @_;
+ undef $self->{error};
+
+ # Find the SQL statement and the arguments to use.
+ my $sql;
+ my @search = ();
+ if (!defined $type || $type eq '') {
+ ($sql) = $self->acls_all;
+ } else {
+ if ($type eq 'entry') {
+ if (@args == 0) {
+ $self->error ('ACL searches require an argument to search');
+ return;
+ } else {
+ ($sql, @search) = $self->acls_entry (@args);
+ }
+ } elsif ($type eq 'empty') {
+ ($sql) = $self->acls_empty;
+ } else {
+ $self->error ("do not know search type: $type");
+ return;
+ }
+ }
+
+ # Do the search.
+ my @acls;
+ eval {
+ my $sth = $self->{dbh}->prepare ($sql);
+ $sth->execute (@search);
+ my $object;
+ while (defined ($object = $sth->fetchrow_arrayref)) {
+ push (@acls, [ @$object ]);
+ }
+ $self->{dbh}->commit;
+ };
+ if ($@) {
+ $self->error ("cannot list ACLs: $@");
+ $self->{dbh}->rollback;
+ return;
+ }
+ return @acls;
+}
+
+# Returns all ACL entries contained in owner ACLs for matching objects.
+# Objects are specified by type and name, which may be SQL wildcard
+# expressions. Each list member will be a pair of ACL scheme and ACL
+# identifier, with duplicates removed. On error and for no matching entries,
+# the empty list will be returned. To distinguish between an empty return and
+# an error, call error(), which will return undef if there was no error.
+sub owners {
+ my ($self, $type, $name) = @_;
+ undef $self->{error};
+ my @lines;
+ eval {
+ my $sql = 'select distinct ae_scheme, ae_identifier from acl_entries,
+ acls, objects where ae_id = ac_id and ac_id = ob_owner and
+ ob_type like ? and ob_name like ? order by ae_scheme,
+ ae_identifier';
+ my $sth = $self->{dbh}->prepare ($sql);
+ $sth->execute ($type, $name);
+ my $object;
+ while (defined ($object = $sth->fetchrow_arrayref)) {
+ push (@lines, [ @$object ]);
+ }
+ $self->{dbh}->commit;
+ };
+ if ($@) {
+ $self->error ("cannot report on owners: $@");
+ $self->{dbh}->rollback;
+ return;
+ }
+ return @lines;
+}
+
+1;
+__DATA__
+
+##############################################################################
+# Documentation
+##############################################################################
+
+=head1 NAME
+
+Wallet::Report - Wallet system reporting interface
+
+=for stopwords
+ACL ACLs wildcard Allbery SQL tuples
+
+=head1 SYNOPSIS
+
+ use Wallet::Report;
+ my $report = Wallet::Report->new;
+ my @objects = $report->objects ('type', 'keytab');
+ for my $object (@objects) {
+ print "@$object\n";
+ }
+
+=head1 DESCRIPTION
+
+Wallet::Report provides a mechanism to generate lists and reports on the
+contents of the wallet database. The format of the results returned
+depend on the type of search, but will generally be returned as a list of
+tuples identifying objects, ACLs, or ACL entries.
+
+To use this object, several configuration variables must be set (at least
+the database configuration). For information on those variables and how
+to set them, see Wallet::Config(3). For more information on the normal
+user interface to the wallet server, see Wallet::Server(3).
+
+=head1 CLASS METHODS
+
+=over 4
+
+=item new()
+
+Creates a new wallet report object and connects to the database. On any
+error, this method throws an exception.
+
+=back
+
+=head1 INSTANCE METHODS
+
+For all methods that can fail, the caller should call error() after a
+failure to get the error message. For all methods that return lists, if
+they return an empty list, the caller should call error() to distinguish
+between an empty report and an error.
+
+=over 4
+
+=item acls([ TYPE [, SEARCH ... ]])
+
+Returns a list of all ACLs matching a search type and string in the
+database, or all ACLs if no search information is given. There are
+currently two search types. C<empty> takes no arguments and will return
+only those ACLs that have no entries within them. C<entry> takes two
+arguments, an entry scheme and a (possibly partial) entry identifier, and
+will return any ACLs containing an entry with that scheme and with an
+identifier containing that value.
+
+The return value is a list of references to pairs of ACL ID and name. For
+example, if there are two ACLs in the database, one with name C<ADMIN> and
+ID 1 and one with name C<group/admins> and ID 3, acls() with no arguments
+would return:
+
+ ([ 1, 'ADMIN' ], [ 3, 'group/admins' ])
+
+Returns the empty list on failure. An error can be distinguished from
+empty search results by calling error(). error() is guaranteed to return
+the error message if there was an error and undef if there was no error.
+
+=item error()
+
+Returns the error of the last failing operation or undef if no operations
+have failed. Callers should call this function to get the error message
+after an undef return from any other instance method.
+
+=item objects([ TYPE [, SEARCH ... ]])
+
+Returns a list of all objects matching a search type and string in the
+database, or all objects in the database if no search information is
+given.
+
+There are four types of searches currently. C<type>, with a given type,
+will return only those entries where the type matches the given type.
+C<owner>, with a given owner, will only return those objects owned by the
+given ACL name or ID. C<flag>, with a given flag name, will only return
+those items with a flag set to the given value. C<acl> operates like
+C<owner>, but will return only those objects that have the given ACL name
+or ID on any of the possible ACL settings, not just owner.
+
+The return value is a list of references to pairs of type and name. For
+example, if two objects existed in the database, both of type C<keytab>
+and with values C<host/example.com> and C<foo>, objects() with no
+arguments would return:
+
+ ([ 'keytab', 'host/example.com' ], [ 'keytab', 'foo' ])
+
+Returns the empty list on failure. To distinguish between this and an
+empty search result, the caller should call error(). error() is
+guaranteed to return the error message if there was an error and undef if
+there was no error.
+
+=item owners(TYPE, NAME)
+
+Returns a list of all ACL lines contained in owner ACLs for objects
+matching TYPE and NAME, which are interpreted as SQL patterns using C<%>
+as a wildcard. The return value is a list of references to pairs of
+schema and identifier, with duplicates removed.
+
+Returns the empty list on failure. To distinguish between this and no
+matches, the caller should call error(). error() is guaranteed to return
+the error message if there was an error and undef if there was no error.
+
+=back
+
+=head1 SEE ALSO
+
+Wallet::Config(3), Wallet::Server(3)
+
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
+
+=head1 AUTHOR
+
+Russ Allbery <rra@stanford.edu> and Jon Robertson <jonrober@stanford.edu>.
+
+=cut
diff --git a/perl/Wallet/Schema.pm b/perl/Wallet/Schema.pm
index 2fb3d64..589a15d 100644
--- a/perl/Wallet/Schema.pm
+++ b/perl/Wallet/Schema.pm
@@ -1,8 +1,7 @@
# Wallet::Schema -- Database schema for the wallet system.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -21,7 +20,7 @@ use DBI;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.05';
+$VERSION = '0.06';
##############################################################################
# Data manipulation
@@ -134,6 +133,10 @@ __DATA__
Wallet::Schema - Database schema for the wallet system
+=for stopwords
+SQL ACL API APIs enums Enums Keytab Backend keytab backend enctypes
+enctype Allbery
+
=head1 SYNOPSIS
use Wallet::Schema;
@@ -158,30 +161,30 @@ MySQL and may require some modifications for other databases.
=item new()
-Instantiates a new Wallet::Schema object. This parses the documentation and
-extracts the schema, but otherwise doesn't do anything.
+Instantiates a new Wallet::Schema object. This parses the documentation
+and extracts the schema, but otherwise doesn't do anything.
=item create(DBH)
-Given a connected database handle, runs the SQL commands necessary to create
-the wallet database in an otherwise empty database. This method will not
-drop any existing tables and will therefore fail if a wallet database has
-already been created. On any error, this method will throw a database
-exception.
+Given a connected database handle, runs the SQL commands necessary to
+create the wallet database in an otherwise empty database. This method
+will not drop any existing tables and will therefore fail if a wallet
+database has already been created. On any error, this method will throw a
+database exception.
=item drop(DBH)
Given a connected database handle, drop all of the wallet tables from that
-database if any of those tables exist. This method will only remove tables
-that are part of the current schema or one of the previous known schema and
-won't remove other tables. On any error, this method will throw a database
-exception.
+database if any of those tables exist. This method will only remove
+tables that are part of the current schema or one of the previous known
+schema and won't remove other tables. On any error, this method will
+throw a database exception.
=item sql()
-Returns the schema and the population of the normalization tables as a list
-of SQL commands to run to create the wallet database in an otherwise empty
-database.
+Returns the schema and the population of the normalization tables as a
+list of SQL commands to run to create the wallet database in an otherwise
+empty database.
=back
@@ -189,8 +192,8 @@ database.
=head2 Normalization Tables
-The following are normalization tables used to constrain the values in other
-tables.
+The following are normalization tables used to constrain the values in
+other tables.
Holds the supported flag names:
@@ -222,16 +225,16 @@ Holds the supported ACL schemes and their corresponding Perl classes:
values ('netdb-root', 'Wallet::ACL::NetDB::Root');
If you have extended the wallet to support additional object types or
-additional ACL schemes, you will want to add additional rows to these tables
-mapping those types or schemes to Perl classes that implement the object or
-ACL verifier APIs.
+additional ACL schemes, you will want to add additional rows to these
+tables mapping those types or schemes to Perl classes that implement the
+object or ACL verifier APIs.
=head2 ACL Tables
-A wallet ACL consists of zero or more ACL entries, each of which is a scheme
-and an identifier. The scheme identifies the check that should be performed
-and the identifier is additional scheme-specific information. Each ACL
-references entries in the following table:
+A wallet ACL consists of zero or more ACL entries, each of which is a
+scheme and an identifier. The scheme identifies the check that should be
+performed and the identifier is additional scheme-specific information.
+Each ACL references entries in the following table:
create table acls
(ac_id integer auto_increment primary key,
@@ -250,8 +253,9 @@ in:
create index ae_id on acl_entries (ae_id);
ACLs may be referred to in the API via either the numeric ID or the
-human-readable name, but internally ACLs are always referenced by numeric ID
-so that they can be renamed without requiring complex data modifications.
+human-readable name, but internally ACLs are always referenced by numeric
+ID so that they can be renamed without requiring complex data
+modifications.
Currently, the ACL named C<ADMIN> (case-sensitive) is special-cased in the
Wallet::Server code and granted global access.
@@ -270,17 +274,18 @@ table.
ah_on datetime not null);
create index ah_acl on acl_history (ah_acl);
-ah_action must be one of C<create>, C<destroy>, C<add>, or C<remove> (enums
-aren't used for compatibility with databases other than MySQL). For a
-change of type create or destroy, only the action and the trace records (by,
-from, and on) are stored. For a change to the lines of an ACL, the scheme
-and identifier of the line that was added or removed is included. Note that
-changes to the ACL name are not recorded; ACLs are always tracked by
-system-generated ID, so name changes are purely cosmetic.
+ah_action must be one of C<create>, C<destroy>, C<add>, or C<remove>
+(enums aren't used for compatibility with databases other than MySQL).
+For a change of type create or destroy, only the action and the trace
+records (by, from, and on) are stored. For a change to the lines of an
+ACL, the scheme and identifier of the line that was added or removed is
+included. Note that changes to the ACL name are not recorded; ACLs are
+always tracked by system-generated ID, so name changes are purely
+cosmetic.
-ah_by stores the authenticated identity that made the change, ah_from stores
-the host from which they made the change, and ah_on stores the time the
-change was made.
+ah_by stores the authenticated identity that made the change, ah_from
+stores the host from which they made the change, and ah_on stores the time
+the change was made.
=head2 Object Tables
@@ -312,13 +317,13 @@ table:
create index ob_expires on objects (ob_expires);
Object names are not globally unique but only unique within their type, so
-the table has a joint primary key. Each object has an owner and then up to
-five more specific ACLs. The owner provides permission for get, store, and
-show operations if no more specific ACL is set. It does not provide
+the table has a joint primary key. Each object has an owner and then up
+to five more specific ACLs. The owner provides permission for get, store,
+and show operations if no more specific ACL is set. It does not provide
permission for destroy or flags.
-The ob_acl_flags ACL controls who can set flags on this object. Each object
-may have zero or more flags associated with it:
+The ob_acl_flags ACL controls who can set flags on this object. Each
+object may have zero or more flags associated with it:
create table flags
(fl_type varchar(16)
@@ -349,36 +354,37 @@ this table:
oh_on datetime not null);
create index oh_object on object_history (oh_type, oh_name);
-oh_action must be one of C<create>, C<destroy>, C<get>, C<store>, or C<set>.
-oh_field must be one of C<owner>, C<acl_get>, C<acl_store>, C<acl_show>,
-C<acl_destroy>, C<acl_flags>, C<expires>, C<flags>, or C<type_data>. Enums
-aren't used for compatibility with databases other than MySQL.
-
-For a change of type create, get, store, or destroy, only the action and the
-trace records (by, from, and on) are stored. For changes to columns or to
-the flags table, oh_field takes what attribute is changed, oh_from takes the
-previous value converted to a string and oh_to takes the next value
-similarly converted to a string. The special field value "type_data" is
-used when type-specific data is changed, and in that case (and only that
-case) some type-specific name for the data being changed is stored in
-oh_type_field.
+oh_action must be one of C<create>, C<destroy>, C<get>, C<store>, or
+C<set>. oh_field must be one of C<owner>, C<acl_get>, C<acl_store>,
+C<acl_show>, C<acl_destroy>, C<acl_flags>, C<expires>, C<flags>, or
+C<type_data>. Enums aren't used for compatibility with databases other
+than MySQL.
+
+For a change of type create, get, store, or destroy, only the action and
+the trace records (by, from, and on) are stored. For changes to columns
+or to the flags table, oh_field takes what attribute is changed, oh_from
+takes the previous value converted to a string and oh_to takes the next
+value similarly converted to a string. The special field value
+"type_data" is used when type-specific data is changed, and in that case
+(and only that case) some type-specific name for the data being changed is
+stored in oh_type_field.
When clearing a flag, oh_old will have the name of the flag and oh_new
will be null. When setting a flag, oh_old will be null and oh_new will
have the name of the flag.
-oh_by stores the authenticated identity that made the change, oh_from stores
-the host from which they made the change, and oh_on stores the time the
-change was made.
+oh_by stores the authenticated identity that made the change, oh_from
+stores the host from which they made the change, and oh_on stores the time
+the change was made.
=head2 Keytab Backend Data
-The keytab backend supports synchronizing keys with an external system. The
-permitted external systems are listed in a normalization table:
+The keytab backend has stub support for synchronizing keys with an
+external system, although no external systems are currently supported.
+The permitted external systems are listed in a normalization table:
create table sync_targets
(st_name varchar(255) primary key);
- insert into sync_targets (st_name) values ('kaserver');
and then the synchronization targets for a given keytab are stored in this
table:
@@ -407,16 +413,16 @@ and then the restrictions for a given keytab are stored in this table:
primary key (ke_name, ke_enctype));
create index ke_name on keytab_enctypes (ke_name);
-To use this functionality, you will need to populate the enctypes table with
-the enctypes that a keytab may be restricted to. Currently, there is no
-automated mechanism to do this.
+To use this functionality, you will need to populate the enctypes table
+with the enctypes that a keytab may be restricted to. Currently, there is
+no automated mechanism to do this.
=head1 SEE ALSO
wallet-backend(8)
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/Wallet/Server.pm b/perl/Wallet/Server.pm
index d4e6a91..dd596c4 100644
--- a/perl/Wallet/Server.pm
+++ b/perl/Wallet/Server.pm
@@ -1,8 +1,7 @@
# Wallet::Server -- Wallet system server implementation.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -24,7 +23,7 @@ use Wallet::Schema;
# This version should be increased on any code change to this module. Always
# use two digits for the minor version with a leading zero if necessary so
# that it will sort properly.
-$VERSION = '0.07';
+$VERSION = '0.08';
##############################################################################
# Utility methods
@@ -715,6 +714,10 @@ __END__
Wallet::Server - Wallet system server implementation
+=for stopwords
+keytabs metadata backend HOSTNAME ACL timestamp ACL's nul Allbery
+backend-specific wallet-backend
+
=head1 SYNOPSIS
use Wallet::Server;
@@ -726,8 +729,8 @@ Wallet::Server - Wallet system server implementation
Wallet::Server is the top-level class that implements the wallet server.
The wallet is a system for storing, generating, and retrieving secure
information such as Kerberos keytabs. The server maintains metadata about
-the objects, checks access against ACLs, and dispatches requests for objects
-to backend implementations for that object type.
+the objects, checks access against ACLs, and dispatches requests for
+objects to backend implementations for that object type.
Wallet::Server is normally instantiated and used by B<wallet-backend>, a
thin wrapper around this object that determines the authenticated remote
@@ -735,8 +738,8 @@ user and gets user input and then calls the appropriate method of this
object.
To use this object, several configuration variables must be set (at least
-the database configuration). For information on those variables and how to
-set them, see Wallet::Config(3).
+the database configuration). For information on those variables and how
+to set them, see Wallet::Config(3).
=head1 CLASS METHODS
@@ -766,11 +769,12 @@ failure to get the error message.
Gets or sets the ACL type ACL to ID for the object identified by TYPE and
NAME. ACL should be one of C<get>, C<store>, C<show>, C<destroy>, or
-C<flags>. If ID is not given, returns the current setting of that ACL as a
-numeric ACL ID or undef if that ACL isn't set or on failure. To distinguish
-between an ACL that isn't set and a failure to retrieve the ACL, the caller
-should call error() after an undef return. If error() also returns undef,
-that ACL wasn't set; otherwise, error() will return the error message.
+C<flags>. If ID is not given, returns the current setting of that ACL as
+a numeric ACL ID or undef if that ACL isn't set or on failure. To
+distinguish between an ACL that isn't set and a failure to retrieve the
+ACL, the caller should call error() after an undef return. If error()
+also returns undef, that ACL wasn't set; otherwise, error() will return
+the error message.
If ID is given, sets the specified ACL to ID, which can be either the name
of an ACL or a numeric ACL ID. To set an ACL, the current user must be
@@ -799,64 +803,65 @@ failure.
Destroys the ACL identified by ID, which may be either the ACL name or its
numeric ID. This call will fail if the ACL is still referenced by any
-object. The ADMIN ACL may not be destroyed. To destroy an ACL, the current
-user must be authorized by the ADMIN ACL. Returns true on success and false
-on failure.
+object. The ADMIN ACL may not be destroyed. To destroy an ACL, the
+current user must be authorized by the ADMIN ACL. Returns true on success
+and false on failure.
=item acl_history(ID)
-Returns the history of the ACL identified by ID, which may be either the ACL
-name or its numeric ID. To see the history of an ACL, the current user must
-be authorized by the ADMIN ACL. Each change that modifies the ACL (not
-counting changes in the name of the ACL) will be represented by two lines.
-The first line will have a timestamp of the change followed by a description
-of the change, and the second line will give the user who made the change
-and the host from which the change was made. Returns undef on failure.
+Returns the history of the ACL identified by ID, which may be either the
+ACL name or its numeric ID. To see the history of an ACL, the current
+user must be authorized by the ADMIN ACL. Each change that modifies the
+ACL (not counting changes in the name of the ACL) will be represented by
+two lines. The first line will have a timestamp of the change followed by
+a description of the change, and the second line will give the user who
+made the change and the host from which the change was made. Returns
+undef on failure.
=item acl_remove(ID, SCHEME, IDENTIFIER)
Removes from the ACL identified by ID the entry matching SCHEME and
IDENTIFIER. ID may be either the name of the ACL or its numeric ID. The
last entry in the ADMIN ACL cannot be removed. To remove an entry from an
-ACL, the current user must be authorized by the ADMIN ACL. Returns true on
-success and false on failure.
+ACL, the current user must be authorized by the ADMIN ACL. Returns true
+on success and false on failure.
=item acl_rename(OLD, NEW)
Renames the ACL identified by OLD to NEW. This changes the human-readable
-name, not the underlying numeric ID, so the ACL's associations with objects
-will be unchanged. The ADMIN ACL may not be renamed. OLD may be either the
-current name or the numeric ID. NEW must not be all-numeric. To rename an
-ACL, the current user must be authorized by the ADMIN ACL. Returns true on
-success and false on failure.
+name, not the underlying numeric ID, so the ACL's associations with
+objects will be unchanged. The ADMIN ACL may not be renamed. OLD may be
+either the current name or the numeric ID. NEW must not be all-numeric.
+To rename an ACL, the current user must be authorized by the ADMIN ACL.
+Returns true on success and false on failure.
=item acl_show(ID)
Returns a human-readable description, including membership, of the ACL
identified by ID, which may be either the ACL name or its numeric ID. To
-show an ACL, the current user must be authorized by the ADMIN ACL (although
-be aware that anyone with show access to an object can see the membership of
-ACLs associated with that object through the show() method). Returns the
-human-readable description on success and undef on failure.
+show an ACL, the current user must be authorized by the ADMIN ACL
+(although be aware that anyone with show access to an object can see the
+membership of ACLs associated with that object through the show() method).
+Returns the human-readable description on success and undef on failure.
=item attr(TYPE, NAME, ATTRIBUTE [, VALUE ...])
Sets or retrieves a given object attribute. Attributes are used to store
-backend-specific information for a particular object type and ATTRIBUTE must
-be an attribute type known to the underlying object implementation.
+backend-specific information for a particular object type and ATTRIBUTE
+must be an attribute type known to the underlying object implementation.
If VALUE is not given, returns the values of that attribute, if any, as a
list. On error, returns the empty list. To distinguish between an error
-and an empty return, call error() afterwards. It is guaranteed to return
-undef unless there was an error. To retrieve an attribute setting, the user
-must be authorized by the ADMIN ACL, the show ACL if set, or the owner ACL
-if the show ACL is not set.
+and an empty return, call error() afterward. It is guaranteed to return
+undef unless there was an error. To retrieve an attribute setting, the
+user must be authorized by the ADMIN ACL, the show ACL if set, or the
+owner ACL if the show ACL is not set.
-If VALUE is given, sets the given ATTRIBUTE values to VALUE, which is one or
-more attribute values. Pass the empty string as the only VALUE to clear the
-attribute values. Returns true on success and false on failure. To set an
-attribute value, the user must be authorized by the ADMIN ACL, the store ACL
-if set, or the owner ACL if the store ACL is not set.
+If VALUE is given, sets the given ATTRIBUTE values to VALUE, which is one
+or more attribute values. Pass the empty string as the only VALUE to
+clear the attribute values. Returns true on success and false on failure.
+To set an attribute value, the user must be authorized by the ADMIN ACL,
+the store ACL if set, or the owner ACL if the store ACL is not set.
=item autocreate(TYPE, NAME)
@@ -878,9 +883,9 @@ for the existence of the object.
=item create(TYPE, NAME)
-Creates a new object of type TYPE and name NAME. TYPE must be a recognized
-type for which the wallet system has a backend implementation. Returns true
-on success and false on failure.
+Creates a new object of type TYPE and name NAME. TYPE must be a
+recognized type for which the wallet system has a backend implementation.
+Returns true on success and false on failure.
To create an object using this method, the current user must be authorized
by the ADMIN ACL. Use autocreate() to create objects based on the default
@@ -889,18 +894,18 @@ owner as determined by the wallet configuration.
=item destroy(TYPE, NAME)
Destroys the object identified by TYPE and NAME. This destroys any data
-that the wallet had saved about the object, may remove the underlying object
-from other external systems, and destroys the wallet database entry for the
-object. To destroy an object, the current user must be authorized by the
-ADMIN ACL or the destroy ACL on the object; the owner ACL is not sufficient.
-Returns true on success and false on failure.
+that the wallet had saved about the object, may remove the underlying
+object from other external systems, and destroys the wallet database entry
+for the object. To destroy an object, the current user must be authorized
+by the ADMIN ACL or the destroy ACL on the object; the owner ACL is not
+sufficient. Returns true on success and false on failure.
=item dbh()
-Returns the database handle of a Wallet::Server object. This is used mostly
-for testing; normally, clients should perform all actions through the
-Wallet::Server object to ensure that authorization and history logging is
-done properly.
+Returns the database handle of a Wallet::Server object. This is used
+mostly for testing; normally, clients should perform all actions through
+the Wallet::Server object to ensure that authorization and history logging
+is done properly.
=item error()
@@ -910,12 +915,12 @@ after an undef return from any other instance method.
=item expires(TYPE, NAME [, EXPIRES])
-Gets or sets the expiration for the object identified by TYPE and NAME. If
-EXPIRES is not given, returns the current expiration or undef if no
-expiration is set or on an error. To distinguish between an expiration that
-isn't set and a failure to retrieve the expiration, the caller should call
-error() after an undef return. If error() also returns undef, that ACL
-wasn't set; otherwise, error() will return the error message.
+Gets or sets the expiration for the object identified by TYPE and NAME.
+If EXPIRES is not given, returns the current expiration or undef if no
+expiration is set or on an error. To distinguish between an expiration
+that isn't set and a failure to retrieve the expiration, the caller should
+call error() after an undef return. If error() also returns undef, that
+ACL wasn't set; otherwise, error() will return the error message.
If EXPIRES is given, sets the expiration to EXPIRES. EXPIRES must be in
the format C<YYYY-MM-DD +HH:MM:SS>, although the time portion may be
@@ -925,23 +930,23 @@ ADMIN ACL. Returns true for success and false for failure.
=item flag_clear(TYPE, NAME, FLAG)
-Clears the flag FLAG on the object identified by TYPE and NAME. To clear a
-flag, the current user must be authorized by the ADMIN ACL or the flags ACL
-on the object.
+Clears the flag FLAG on the object identified by TYPE and NAME. To clear
+a flag, the current user must be authorized by the ADMIN ACL or the flags
+ACL on the object.
=item flag_set(TYPE, NAME, FLAG)
Sets the flag FLAG on the object identified by TYPE and NAME. To set a
-flag, the current user must be authorized by the ADMIN ACL or the flags ACL
-on the object.
+flag, the current user must be authorized by the ADMIN ACL or the flags
+ACL on the object.
=item get(TYPE, NAME)
Returns the data associated with the object identified by TYPE and NAME.
-Depending on the object TYPE, this may generate new data and invalidate any
-existing data or it may return data previously stored or generated. Note
-that this data may be binary and may contain nul characters. To get an
-object, the current user must either be authorized by the owner ACL or
+Depending on the object TYPE, this may generate new data and invalidate
+any existing data or it may return data previously stored or generated.
+Note that this data may be binary and may contain nul characters. To get
+an object, the current user must either be authorized by the owner ACL or
authorized by the get ACL; however, if the get ACL is set, the owner ACL
will not be checked. Being a member of the ADMIN ACL does not provide any
special privileges to get objects.
@@ -951,48 +956,49 @@ between undef and the empty string, which is valid object data.
=item history(TYPE, NAME)
-Returns (as a string) the human-readable history of the object identified by
-TYPE and NAME, or undef on error. To see the object history, the current
-user must be a member of the ADMIN ACL, authorized by the show ACL, or
-authorized by the owner ACL; however, if the show ACL is set, the owner ACL
-will not be checked.
+Returns (as a string) the human-readable history of the object identified
+by TYPE and NAME, or undef on error. To see the object history, the
+current user must be a member of the ADMIN ACL, authorized by the show
+ACL, or authorized by the owner ACL; however, if the show ACL is set, the
+owner ACL will not be checked.
=item owner(TYPE, NAME [, OWNER])
-Gets or sets the owner for the object identified by TYPE and NAME. If OWNER
-is not given, returns the current owner as a numeric ACL ID or undef if no
-owner is set or on an error. To distinguish between an owner that isn't set
-and a failure to retrieve the owner, the caller should call error() after an
-undef return. If error() also returns undef, that ACL wasn't set;
-otherwise, error() will return the error message.
+Gets or sets the owner for the object identified by TYPE and NAME. If
+OWNER is not given, returns the current owner as a numeric ACL ID or undef
+if no owner is set or on an error. To distinguish between an owner that
+isn't set and a failure to retrieve the owner, the caller should call
+error() after an undef return. If error() also returns undef, that ACL
+wasn't set; otherwise, error() will return the error message.
-If OWNER is given, sets the owner to OWNER, which may be either the name of
-an ACL or a numeric ACL ID. To set an owner, the current user must be
+If OWNER is given, sets the owner to OWNER, which may be either the name
+of an ACL or a numeric ACL ID. To set an owner, the current user must be
authorized by the ADMIN ACL. Returns true for success and false for
failure.
-The owner of an object is permitted to get, store, and show that object, but
-cannot destroy or set flags on that object without being listed on those
-ACLs as well.
+The owner of an object is permitted to get, store, and show that object,
+but cannot destroy or set flags on that object without being listed on
+those ACLs as well.
=item show(TYPE, NAME)
-Returns (as a string) a human-readable representation of the metadata stored
-for the object identified by TYPE and NAME, or undef on error. Included is
-the metadata and entries of any ACLs associated with the object. To show an
-object, the current user must be a member of the ADMIN ACL, authorized by
-the show ACL, or authorized by the owner ACL; however, if the show ACL is
-set, the owner ACL will not be checked.
+Returns (as a string) a human-readable representation of the metadata
+stored for the object identified by TYPE and NAME, or undef on error.
+Included is the metadata and entries of any ACLs associated with the
+object. To show an object, the current user must be a member of the ADMIN
+ACL, authorized by the show ACL, or authorized by the owner ACL; however,
+if the show ACL is set, the owner ACL will not be checked.
=item store(TYPE, NAME, DATA)
-Stores DATA for the object identified with TYPE and NAME for later retrieval
-with get. Not all object types support this. Note that DATA may be binary
-and may contain nul characters. To store an object, the current user must
-either be authorized by the owner ACL or authorized by the store ACL;
-however, if the store ACL is set, the owner ACL is not checked. Being a
-member of the ADMIN ACL does not provide any special privileges to store
-objects. Returns true on success and false on failure.
+Stores DATA for the object identified with TYPE and NAME for later
+retrieval with get. Not all object types support this. Note that DATA
+may be binary and may contain nul characters. To store an object, the
+current user must either be authorized by the owner ACL or authorized by
+the store ACL; however, if the store ACL is set, the owner ACL is not
+checked. Being a member of the ADMIN ACL does not provide any special
+privileges to store objects. Returns true on success and false on
+failure.
=back
@@ -1000,8 +1006,8 @@ objects. Returns true on success and false on failure.
wallet-backend(8)
-This module is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This module is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/perl/t/acl.t b/perl/t/acl.t
index e46b7f8..95aa763 100755
--- a/perl/t/acl.t
+++ b/perl/t/acl.t
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/api.t -- Tests for the wallet ACL API.
#
diff --git a/perl/t/admin.t b/perl/t/admin.t
index 4b8302d..e22088e 100755
--- a/perl/t/admin.t
+++ b/perl/t/admin.t
@@ -1,16 +1,16 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/admin.t -- Tests for wallet administrative interface.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
-use Test::More tests => 29;
+use Test::More tests => 16;
use Wallet::Admin;
+use Wallet::Report;
use Wallet::Schema;
use Wallet::Server;
@@ -26,10 +26,11 @@ is ($admin->initialize ('admin@EXAMPLE.COM'), 1,
' and initialization succeeds');
# We have an empty database, so we should see no objects and one ACL.
-my @objects = $admin->list_objects;
+my $report = Wallet::Report->new;
+my @objects = $report->objects;
is (scalar (@objects), 0, 'No objects in the database');
-is ($admin->error, undef, ' and no error');
-my @acls = $admin->list_acls;
+is ($report->error, undef, ' and no error');
+my @acls = $report->acls;
is (scalar (@acls), 1, 'One ACL in the database');
is ($acls[0][0], 1, ' and that is ACL ID 1');
is ($acls[0][1], 'ADMIN', ' with the right name');
@@ -37,42 +38,20 @@ is ($acls[0][1], 'ADMIN', ' with the right name');
# Register a base object so that we can create a simple object.
is ($admin->register_object ('base', 'Wallet::Object::Base'), 1,
'Registering Wallet::Object::Base works');
-
-# Create an object.
+is ($admin->register_object ('base', 'Wallet::Object::Base'), undef,
+ ' and cannot be registered twice');
$server = eval { Wallet::Server->new ('admin@EXAMPLE.COM', 'localhost') };
is ($@, '', 'Creating a server instance did not die');
is ($server->create ('base', 'service/admin'), 1,
' and creating base:service/admin succeeds');
-# Now, we should see one object.
-@objects = $admin->list_objects;
-is (scalar (@objects), 1, ' and now there is one object');
-is ($objects[0][0], 'base', ' with the right type');
-is ($objects[0][1], 'service/admin', ' and the right name');
-
-# Test registering a new ACL type. We don't have a good way of really using
-# this right now.
+# Test registering a new ACL type.
is ($admin->register_verifier ('base', 'Wallet::ACL::Base'), 1,
'Registering Wallet::ACL::Base works');
-
-# Create another ACL.
-is ($server->acl_create ('first'), 1, 'ACL creation succeeds');
-@acls = $admin->list_acls;
-is (scalar (@acls), 2, ' and now there are two ACLs');
-is ($acls[0][0], 1, ' and the first ID is correct');
-is ($acls[0][1], 'ADMIN', ' and the first name is correct');
-is ($acls[1][0], 2, ' and the second ID is correct');
-is ($acls[1][1], 'first', ' and the second name is correct');
-
-# Delete that ACL and create another.
-is ($server->acl_create ('second'), 1, 'Second ACL creation succeeds');
-is ($server->acl_destroy ('first'), 1, ' and deletion of the first succeeds');
-@acls = $admin->list_acls;
-is (scalar (@acls), 2, ' and there are still two ACLs');
-is ($acls[0][0], 1, ' and the first ID is still the same');
-is ($acls[0][1], 'ADMIN', ' and the first name is still the same');
-is ($acls[1][0], 3, ' but the second ID has changed');
-is ($acls[1][1], 'second', ' and the second name is correct');
+is ($admin->register_verifier ('base', 'Wallet::ACL::Base'), undef,
+ ' and cannot be registered twice');
+is ($server->acl_add ('ADMIN', 'base', 'foo'), 1,
+ ' and adding a base ACL now works');
# Clean up.
is ($admin->destroy, 1, 'Destruction succeeds');
diff --git a/perl/t/config.t b/perl/t/config.t
index 0d159dc..1377cb8 100755
--- a/perl/t/config.t
+++ b/perl/t/config.t
@@ -1,14 +1,13 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/config.t -- Tests for the wallet server configuration.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
-use Test::More tests => 7;
+use Test::More tests => 6;
# Silence warnings since we're not using use.
package Wallet::Config;
@@ -26,8 +25,6 @@ is ($Wallet::Config::KEYTAB_FLAGS, '-clearpolicy',
' and KEYTAB_FLAGS is correct');
is ($Wallet::Config::KEYTAB_KADMIN, 'kadmin',
' and KEYTAB_KADMIN is correct');
-is ($Wallet::Config::KEYTAB_AFS_KASETKEY, 'kasetkey',
- ' and KEYTAB_AFS_KASETKEY is correct');
is ($Wallet::Config::DB_DRIVER, undef, ' and DB_DRIVER is unset');
# Create a configuration file with a single setting.
diff --git a/perl/t/data/README b/perl/t/data/README
index 4abbaeb..d250d33 100644
--- a/perl/t/data/README
+++ b/perl/t/data/README
@@ -21,6 +21,7 @@ following files:
test.keytab Keytab for an authorized user
test.principal Principal of the authorized user
test.realm Kerberos realm in which to do testing
+ test.krbtype Type of Kerberos server (Heimdal or MIT)
This realm will also need to be configured in your local krb5.conf,
including the admin_server for the realm.
diff --git a/perl/t/data/keytab-fake b/perl/t/data/keytab-fake
index df21294..0ecf264 100755
--- a/perl/t/data/keytab-fake
+++ b/perl/t/data/keytab-fake
@@ -1,5 +1,4 @@
#!/bin/sh
-# $Id$
#
# keytab-fake -- Fake keytab-backend implementation.
#
diff --git a/perl/t/data/keytab.conf b/perl/t/data/keytab.conf
index eb105e2..484443f 100644
--- a/perl/t/data/keytab.conf
+++ b/perl/t/data/keytab.conf
@@ -1,5 +1,3 @@
-# $Id$
-#
# This is the remctl configuration used for testing the keytab backend's
# ability to retrieve existing keytabs through remctl. Currently the only
# supported and used command is keytab retrieve. The ACL is written on
diff --git a/perl/t/data/netdb-fake b/perl/t/data/netdb-fake
index 56744a7..ae5be18 100755
--- a/perl/t/data/netdb-fake
+++ b/perl/t/data/netdb-fake
@@ -1,5 +1,4 @@
#!/bin/sh
-# $Id$
#
# netdb-fake -- Fake NetDB remctl interface.
#
diff --git a/perl/t/data/netdb.conf b/perl/t/data/netdb.conf
index e7908ed..f08bfaa 100644
--- a/perl/t/data/netdb.conf
+++ b/perl/t/data/netdb.conf
@@ -1,5 +1,3 @@
-# $Id$
-#
# This is the remctl configuration used for testing the NetDB ACL verifier.
# The ACL is written on the fly by the test program.
diff --git a/perl/t/file.t b/perl/t/file.t
index 8eaa0f1..7ab5d75 100755
--- a/perl/t/file.t
+++ b/perl/t/file.t
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/file.t -- Tests for the file object implementation.
#
diff --git a/perl/t/init.t b/perl/t/init.t
index 70085c9..d0fae9f 100755
--- a/perl/t/init.t
+++ b/perl/t/init.t
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/init.t -- Tests for database initialization.
#
diff --git a/perl/t/kadmin.t b/perl/t/kadmin.t
new file mode 100755
index 0000000..bbcb15a
--- /dev/null
+++ b/perl/t/kadmin.t
@@ -0,0 +1,109 @@
+#!/usr/bin/perl -w
+#
+# t/kadmin.t -- Tests for the kadmin object implementation.
+#
+# Written by Jon Robertson <jonrober@stanford.edu>
+# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+use POSIX qw(strftime);
+use Test::More tests => 32;
+
+BEGIN { $Wallet::Config::KEYTAB_TMP = '.' }
+
+use Wallet::Admin;
+use Wallet::Config;
+use Wallet::Kadmin;
+use Wallet::Kadmin::MIT;
+
+# Only load Wallet::Kadmin::Heimdal if a required module is found.
+my $heimdal_kadm5 = 0;
+eval 'use Heimdal::Kadm5';
+if (!$@) {
+ $heimdal_kadm5 = 1;
+ require Wallet::Kadmin::Heimdal;
+}
+
+use lib 't/lib';
+use Util;
+
+# Test creating an MIT object and seeing if the callback works.
+$Wallet::Config::KEYTAB_KRBTYPE = 'MIT';
+my $kadmin = Wallet::Kadmin->new;
+ok (defined ($kadmin), 'MIT kadmin object created');
+my $callback = sub { return 1 };
+$kadmin->fork_callback ($callback);
+is ($kadmin->{fork_callback} (), 1, ' and callback works');
+$callback = sub { return 2 };
+$kadmin->fork_callback ($callback);
+is ($kadmin->{fork_callback} (), 2, ' and changing it works');
+
+# Check principal validation in the Wallet::Kadmin::MIT module. This is
+# specific to that module, since Heimdal doesn't require passing the principal
+# through the kadmin client.
+for my $bad (qw{service\* = host/foo+bar host/foo/bar /bar bar/ rcmd.foo}) {
+ ok (! Wallet::Kadmin::MIT->valid_principal ($bad),
+ "Invalid principal name $bad");
+}
+for my $good (qw{service service/foo bar foo/bar host/example.org
+ aservice/foo}) {
+ ok (Wallet::Kadmin::MIT->valid_principal ($good),
+ "Valid principal name $good");
+}
+
+# Test creating a Heimdal object. We deliberately connect without
+# configuration to get the error. That tests that we can find the Heimdal
+# module and it dies how it should.
+SKIP: {
+ skip 'Heimdal::Kadm5 not installed', 3 unless $heimdal_kadm5;
+ undef $Wallet::Config::KEYTAB_PRINCIPAL;
+ undef $Wallet::Config::KEYTAB_FILE;
+ undef $Wallet::Config::KEYTAB_REALM;
+ undef $kadmin;
+ $Wallet::Config::KEYTAB_KRBTYPE = 'Heimdal';
+ $kadmin = eval { Wallet::Kadmin->new };
+ is ($kadmin, undef, 'Heimdal fails properly');
+ is ($@, "keytab object implementation not configured\n",
+ ' with the right error');
+}
+
+# Now, check the generic API. We can run this test no matter which
+# implementation is configured. This retests some things that are also tested
+# by the keytab test, but specifically through the Wallet::Kadmin API.
+SKIP: {
+ skip 'no keytab configuration', 14 unless -f 't/data/test.keytab';
+
+ # Set up our configuration.
+ $Wallet::Config::KEYTAB_FILE = 't/data/test.keytab';
+ $Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal');
+ $Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm');
+ $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype');
+ $Wallet::Config::KEYTAB_TMP = '.';
+
+ # Create the object and clean up the principal we're going to use.
+ $kadmin = eval { Wallet::Kadmin->new };
+ ok (defined $kadmin, 'Creating Wallet::Kadmin object succeeds');
+ is ($@, '', ' and there is no error');
+ is ($kadmin->destroy ('wallet/one'), 1, 'Deleting wallet/one works');
+ is ($kadmin->exists ('wallet/one'), 0, ' and it does not exist');
+
+ # Create the principal and check that keytab returns something. We'll
+ # check the details of the return in the keytab check.
+ is ($kadmin->create ('wallet/one'), 1, 'Creating wallet/one works');
+ is ($kadmin->exists ('wallet/one'), 1, ' and it now exists');
+ my $data = $kadmin->keytab_rekey ('wallet/one');
+ ok (defined ($data), ' and retrieving a keytab works');
+ is (keytab_valid ($data, 'wallet/one'), 1,
+ ' and works for authentication');
+
+ # Delete the principal and confirm behavior.
+ is ($kadmin->destroy ('wallet/one'), 1, 'Deleting principal works');
+ is ($kadmin->exists ('wallet/one'), 0, ' and now it does not exist');
+ is ($kadmin->keytab_rekey ('wallet/one', './tmp.keytab'), undef,
+ ' and retrieving the keytab does not work');
+ ok (! -f './tmp.keytab', ' and no file was created');
+ like ($kadmin->error, qr%^error creating keytab for wallet/one%,
+ ' and the right error message is set');
+ is ($kadmin->destroy ('wallet/one'), 1, ' and deleting it again works');
+}
diff --git a/perl/t/keytab.t b/perl/t/keytab.t
index c1348d4..046da9c 100755
--- a/perl/t/keytab.t
+++ b/perl/t/keytab.t
@@ -1,18 +1,21 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/keytab.t -- Tests for the keytab object implementation.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2009, 2010
+# Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
use POSIX qw(strftime);
-use Test::More tests => 223;
+use Test::More tests => 135;
+
+BEGIN { $Wallet::Config::KEYTAB_TMP = '.' }
use Wallet::Admin;
use Wallet::Config;
+use Wallet::Kadmin;
use Wallet::Object::Keytab;
use lib 't/lib';
@@ -25,7 +28,7 @@ my %enctype =
('triple des cbc mode with hmac/sha1' => 'des3-cbc-sha1',
'des cbc mode with crc-32' => 'des-cbc-crc',
'des cbc mode with rsa-md5' => 'des-cbc-md5',
- 'aes-256 cts mode with 96-bit sha-1 hmac' => 'aes256-cts',
+ 'aes-256 cts mode with 96-bit sha-1 hmac' => 'aes256-cts-hmac-sha1-96',
'arcfour with hmac/md5' => 'rc4-hmac');
# Some global defaults to use.
@@ -57,60 +60,51 @@ sub system_quiet {
# been set up.
sub create {
my ($principal) = @_;
- my @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, '-k',
- '-t', $Wallet::Config::KEYTAB_FILE,
- '-r', $Wallet::Config::KEYTAB_REALM,
- '-q', "addprinc -clearpolicy -randkey $principal");
- system_quiet ($Wallet::Config::KEYTAB_KADMIN, @args);
+ my $kadmin = Wallet::Kadmin->new;
+ return $kadmin->create ($principal);
}
# Destroy a principal out of Kerberos. Only usable once the configuration has
# been set up.
sub destroy {
my ($principal) = @_;
- my @args = ('-p', $Wallet::Config::KEYTAB_PRINCIPAL, '-k',
- '-t', $Wallet::Config::KEYTAB_FILE,
- '-r', $Wallet::Config::KEYTAB_REALM,
- '-q', "delprinc -force $principal");
- system_quiet ($Wallet::Config::KEYTAB_KADMIN, @args);
+ my $kadmin = Wallet::Kadmin->new;
+ return $kadmin->destroy ($principal);
}
-# Check whether a principal exists.
+# Check whether a principal exists. MIT uses kvno and Heimdal uses kgetcred.
+# Note that the Kerberos type may be different than our local userspace, so
+# don't use the Kerberos type to decide here. Instead, check for which
+# program is available on the path.
sub created {
my ($principal) = @_;
$principal .= '@' . $Wallet::Config::KEYTAB_REALM;
local $ENV{KRB5CCNAME} = 'krb5cc_temp';
getcreds ('t/data/test.keytab', $Wallet::Config::KEYTAB_PRINCIPAL);
- return (system_quiet ('kvno', $principal) == 0);
-}
-
-# Given keytab data and the principal, write it to a file and try
-# authenticating using kinit.
-sub valid {
- my ($keytab, $principal) = @_;
- open (KEYTAB, '>', 'keytab') or die "cannot create keytab: $!\n";
- print KEYTAB $keytab;
- close KEYTAB;
- $principal .= '@' . $Wallet::Config::KEYTAB_REALM;
- my $result = getcreds ('keytab', $principal);
- if ($result) {
- unlink 'keytab';
+ if (grep { -x "$_/kvno" } split (':', $ENV{PATH})) {
+ return (system_quiet ('kvno', $principal) == 0);
+ } elsif (grep { -x "$_/kgetcred" } split (':', $ENV{PATH})) {
+ return (system_quiet ('kgetcred', $principal) == 0);
+ } else {
+ warn "# No kvno or kgetcred found\n";
+ return;
}
- return $result;
}
# Given keytab data, write it to a file and try to determine the enctypes of
# the keys present in that file. Returns the enctypes as a list, with UNKNOWN
# for encryption types that weren't recognized. This is an ugly way of doing
-# this.
+# this for MIT. Heimdal is much more straightforward, but MIT ktutil doesn't
+# have the needed abilities.
sub enctypes {
my ($keytab) = @_;
open (KEYTAB, '>', 'keytab') or die "cannot create keytab: $!\n";
print KEYTAB $keytab;
close KEYTAB;
+
+ my @enctypes;
open (KLIST, '-|', 'klist', '-ke', 'keytab')
or die "cannot run klist: $!\n";
- my @enctypes;
local $_;
while (<KLIST>) {
next unless /^ *\d+ /;
@@ -120,26 +114,24 @@ sub enctypes {
push (@enctypes, $enctype);
}
close KLIST;
- unlink 'keytab';
- return sort @enctypes;
-}
-# Given a Wallet::Object::Keytab object, the keytab data, the Kerberos v5
-# principal, and the Kerberos v4 principal, write the keytab to a file,
-# generate a srvtab, and try authenticating using k4start.
-sub valid_srvtab {
- my ($object, $keytab, $k5, $k4) = @_;
- open (KEYTAB, '>', 'keytab') or die "cannot create keytab: $!\n";
- print KEYTAB $keytab;
- close KEYTAB;
- unless ($object->kaserver_srvtab ('keytab', $k5, 'srvtab', $k4)) {
- warn "cannot write srvtab: ", $object->error, "\n";
- return 0;
+ # If that failed, we may have a Heimdal user space instead, so try ktutil.
+ # If we try this directly, it will just hang with MIT ktutil.
+ if ($? != 0) {
+ @enctypes = ();
+ open (KTUTIL, '-|', 'ktutil', '-k', 'keytab', 'list')
+ or die "cannot run ktutil: $!\n";
+ local $_;
+ while (<KTUTIL>) {
+ next unless /^ *\d+ /;
+ my ($string) = /^\s*\d+\s+(\S+)/;
+ next unless $string;
+ push (@enctypes, $string);
+ }
+ close KTUTIL;
}
- $ENV{KRBTKFILE} = 'krb4cc_temp';
- system ("k4start -f srvtab $k4 2>&1 >/dev/null </dev/null");
- unlink 'keytab', 'srvtab', 'krb4cc_temp';
- return ($? == 0) ? 1 : 0;
+ unlink 'keytab';
+ return sort @enctypes;
}
# Use Wallet::Admin to set up the database.
@@ -154,27 +146,15 @@ my $dbh = $admin->dbh;
my $history = '';
my $date = strftime ('%Y-%m-%d %H:%M:%S', localtime $trace[2]);
-# Do some white-box testing of the principal validation regex.
-for my $bad (qw{service\* = host/foo+bar host/foo/bar /bar bar/
- rcmd.foo}) {
- ok (! Wallet::Object::Keytab->valid_principal ($bad),
- "Invalid principal name $bad");
-}
-for my $good (qw{service service/foo bar foo/bar host/example.org
- aservice/foo}) {
- ok (Wallet::Object::Keytab->valid_principal ($good),
- "Valid principal name $good");
-}
-
# Basic keytab creation and manipulation tests.
SKIP: {
- skip 'no keytab configuration', 49 unless -f 't/data/test.keytab';
+ skip 'no keytab configuration', 52 unless -f 't/data/test.keytab';
# Set up our configuration.
$Wallet::Config::KEYTAB_FILE = 't/data/test.keytab';
$Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal');
$Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm');
- $Wallet::Config::KEYTAB_TMP = '.';
+ $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype');
my $realm = $Wallet::Config::KEYTAB_REALM;
# Clean up the principals we're going to use.
@@ -184,17 +164,36 @@ SKIP: {
# Don't destroy the user's Kerberos ticket cache.
$ENV{KRB5CCNAME} = 'krb5cc_test';
+ # Test that object creation without KEYTAB_TMP fails.
+ undef $Wallet::Config::KEYTAB_TMP;
+ $object = eval {
+ Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace)
+ };
+ is ($object, undef, 'Creating keytab without KEYTAB_TMP fails');
+ is ($@, "KEYTAB_TMP configuration variable not set\n",
+ ' with the right error');
+ $Wallet::Config::KEYTAB_TMP = '.';
+
# Okay, now we can test. First, create.
$object = eval {
Wallet::Object::Keytab->create ('keytab', "wallet\nf", $dbh, @trace)
};
is ($object, undef, 'Creating malformed principal fails');
- is ($@, "invalid principal name wallet\nf\n", ' with the right error');
+ if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') {
+ is ($@, "invalid principal name wallet\nf\n", ' with the right error');
+ } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') {
+ like ($@, qr/^error adding principal wallet\nf/,
+ ' with the right error');
+ }
$object = eval {
Wallet::Object::Keytab->create ('keytab', '', $dbh, @trace)
};
is ($object, undef, 'Creating empty principal fails');
- is ($@, "invalid principal name \n", ' with the right error');
+ if ($Wallet::Config::KEYTAB_KRBTYPE eq 'MIT') {
+ is ($@, "invalid principal name \n", ' with the right error');
+ } elsif ($Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal') {
+ like ($@, qr/^error adding principal \@/, ' with the right error');
+ }
$object = eval {
Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace)
};
@@ -209,9 +208,14 @@ SKIP: {
$object = eval {
Wallet::Object::Keytab->create ('keytab', 'wallet/two', $dbh, @trace)
};
- ok (defined ($object), 'Creating an existing principal succeeds');
+ if (defined ($object)) {
+ ok (defined ($object), 'Creating an existing principal succeeds');
+ } else {
+ is ($@, '', 'Creating an existing principal succeeds');
+ }
ok ($object->isa ('Wallet::Object::Keytab'), ' and is the right class');
is ($object->destroy (@trace), 1, ' and destroying it succeeds');
+ is ($object->error, undef, ' with no error message');
ok (! created ('wallet/two'), ' and now it does not exist');
my @name = qw(keytab wallet-test/one);
$object = eval { Wallet::Object::Keytab->create (@name, $dbh, @trace) };
@@ -236,7 +240,7 @@ SKIP: {
is ($object->error, '', ' and getting the keytab works');
}
ok (! -f "./keytab.$$", ' and the temporary file was cleaned up');
- ok (valid ($data, 'wallet/one'), ' and the keytab is valid');
+ ok (keytab_valid ($data, 'wallet/one'), ' and the keytab is valid');
# For right now, this is the only backend type that we have for which we
# can do a get, so test display of the last download information.
@@ -253,18 +257,16 @@ EOO
is ($object->show, $expected, 'Show output is correct');
# Test error handling on keytab retrieval.
- undef $Wallet::Config::KEYTAB_TMP;
- $data = $object->get (@trace);
- is ($data, undef, 'Getting a keytab without a tmp directory fails');
- is ($object->error, 'KEYTAB_TMP configuration variable not set',
- ' with the right error');
- $Wallet::Config::KEYTAB_TMP = '.';
- $Wallet::Config::KEYTAB_KADMIN = '/some/nonexistent/file';
- $data = $object->get (@trace);
- is ($data, undef, 'Cope with a failure to run kadmin');
- like ($object->error, qr{^cannot run /some/nonexistent/file: },
- ' with the right error');
- $Wallet::Config::KEYTAB_KADMIN = 'kadmin';
+ SKIP: {
+ skip 'no kadmin program test for Heimdal', 2
+ if $Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal';
+ $Wallet::Config::KEYTAB_KADMIN = '/some/nonexistent/file';
+ $data = $object->get (@trace);
+ is ($data, undef, 'Cope with a failure to run kadmin');
+ like ($object->error, qr{^cannot run /some/nonexistent/file: },
+ ' with the right error');
+ $Wallet::Config::KEYTAB_KADMIN = 'kadmin';
+ }
destroy ('wallet/one');
$data = $object->get (@trace);
is ($data, undef, 'Getting a keytab for a nonexistent principal fails');
@@ -279,12 +281,16 @@ EOO
};
ok (defined ($object), 'Creating good principal succeeds');
ok (created ('wallet/one'), ' and the principal was created');
- $Wallet::Config::KEYTAB_KADMIN = '/some/nonexistent/file';
- is ($object->destroy (@trace), undef,
- ' and destroying it with bad kadmin fails');
- like ($object->error, qr{^cannot run /some/nonexistent/file: },
- ' with the right error');
- $Wallet::Config::KEYTAB_KADMIN = 'kadmin';
+ SKIP: {
+ skip 'no kadmin program test for Heimdal', 2
+ if $Wallet::Config::KEYTAB_KRBTYPE eq 'Heimdal';
+ $Wallet::Config::KEYTAB_KADMIN = '/some/nonexistent/file';
+ is ($object->destroy (@trace), undef,
+ ' and destroying it with bad kadmin fails');
+ like ($object->error, qr{^cannot run /some/nonexistent/file: },
+ ' with the right error');
+ $Wallet::Config::KEYTAB_KADMIN = 'kadmin';
+ }
is ($object->flag_set ('locked', @trace), 1, ' and setting locked works');
is ($object->destroy (@trace), undef, ' and destroying it fails');
is ($object->error, "cannot destroy keytab:wallet/one: object is locked",
@@ -342,30 +348,33 @@ EOO
is ($@, "keytab object implementation not configured\n",
' with the right error');
$Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm');
- $Wallet::Config::KEYTAB_KADMIN = '/some/nonexistent/file';
+ undef $Wallet::Config::KEYTAB_KRBTYPE;
$object = eval {
Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace)
};
- is ($object, undef, 'Cope with a failure to run kadmin');
- like ($@, qr{^cannot run /some/nonexistent/file: },
- ' with the right error');
- $Wallet::Config::KEYTAB_KADMIN = 'kadmin';
+ is ($object, undef, ' and another');
+ is ($@, "keytab object implementation not configured\n",
+ ' with the right error');
+ $Wallet::Config::KEYTAB_KRBTYPE = 'Active Directory';
+ $object = eval {
+ Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace)
+ };
+ is ($object, undef, ' and one set to an invalid value');
+ is ($@, "unknown KEYTAB_KRBTYPE setting: Active Directory\n",
+ ' with the right error');
+ $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype');
}
# Tests for unchanging support. Skip these if we don't have a keytab or if we
# can't find remctld.
SKIP: {
- skip 'no keytab configuration', 17 unless -f 't/data/test.keytab';
- my @path = (split (':', $ENV{PATH}), '/usr/local/sbin', '/usr/sbin');
- my ($remctld) = grep { -x $_ } map { "$_/remctld" } @path;
- skip 'remctld not found', 17 unless $remctld;
- eval { require Net::Remctl };
- skip 'Net::Remctl not available', 17 if $@;
+ skip 'no keytab configuration', 27 unless -f 't/data/test.keytab';
# Set up our configuration.
$Wallet::Config::KEYTAB_FILE = 't/data/test.keytab';
$Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal');
$Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm');
+ $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype');
$Wallet::Config::KEYTAB_TMP = '.';
my $realm = $Wallet::Config::KEYTAB_REALM;
my $principal = $Wallet::Config::KEYTAB_PRINCIPAL;
@@ -382,41 +391,85 @@ SKIP: {
ok (defined ($two), 'Creating wallet/two succeeds');
is ($two->flag_set ('unchanging', @trace), 1, ' and setting unchanging');
- # Now spawn our remctld server and get a ticket cache.
- remctld_spawn ($remctld, $principal, 't/data/test.keytab',
- 't/data/keytab.conf');
- $ENV{KRB5CCNAME} = 'krb5cc_test';
- getcreds ('t/data/test.keytab', $principal);
- $ENV{KRB5CCNAME} = 'krb5cc_good';
+ # Finally we can test. First the MIT Kerberos tests.
+ SKIP: {
+ skip 'skipping MIT unchanging tests for Heimdal', 12
+ if (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'heimdal');
+
+ # We need remctld and Net::Remctl.
+ my @path = (split (':', $ENV{PATH}), '/usr/local/sbin', '/usr/sbin');
+ my ($remctld) = grep { -x $_ } map { "$_/remctld" } @path;
+ skip 'remctld not found', 12 unless $remctld;
+ eval { require Net::Remctl };
+ skip 'Net::Remctl not available', 12 if $@;
+
+ # Now spawn our remctld server and get a ticket cache.
+ remctld_spawn ($remctld, $principal, 't/data/test.keytab',
+ 't/data/keytab.conf');
+ $ENV{KRB5CCNAME} = 'krb5cc_test';
+ getcreds ('t/data/test.keytab', $principal);
+ $ENV{KRB5CCNAME} = 'krb5cc_good';
+
+ # Do the unchanging tests for MIT Kerberos.
+ is ($one->get (@trace), undef, 'Get without configuration fails');
+ is ($one->error, 'keytab unchanging support not configured',
+ ' with the right error');
+ $Wallet::Config::KEYTAB_REMCTL_CACHE = 'krb5cc_test';
+ is ($one->get (@trace), undef, ' and still fails without host');
+ is ($one->error, 'keytab unchanging support not configured',
+ ' with the right error');
+ $Wallet::Config::KEYTAB_REMCTL_HOST = 'localhost';
+ $Wallet::Config::KEYTAB_REMCTL_PRINCIPAL = $principal;
+ $Wallet::Config::KEYTAB_REMCTL_PORT = 14373;
+ is ($one->get (@trace), undef, ' and still fails without ACL');
+ is ($one->error,
+ "cannot retrieve keytab for wallet/one\@$realm: Access denied",
+ ' with the right error');
+ open (ACL, '>', 'test-acl') or die "cannot create test-acl: $!\n";
+ print ACL "$principal\n";
+ close ACL;
+ is ($one->get (@trace), 'Keytab for wallet/one', 'Now get works');
+ is ($ENV{KRB5CCNAME}, 'krb5cc_good',
+ ' and we did not nuke the cache name');
+ is ($one->get (@trace), 'Keytab for wallet/one',
+ ' and we get the same thing the second time');
+ is ($one->flag_clear ('unchanging', @trace), 1,
+ 'Clearing the unchanging flag works');
+ my $data = $object->get (@trace);
+ ok (defined ($data), ' and getting the keytab works');
+ ok (keytab_valid ($data, 'wallet/one'), ' and the keytab is valid');
+ is ($two->get (@trace), undef, 'Get for wallet/two does not work');
+ is ($two->error,
+ "cannot retrieve keytab for wallet/two\@$realm: bite me",
+ ' with the right error');
+ is ($one->destroy (@trace), 1, 'Destroying wallet/one works');
+ is ($two->destroy (@trace), 1, ' as does destroying wallet/two');
+ remctld_stop;
+ }
- # Finally we can test.
- is ($one->get (@trace), undef, 'Get without configuration fails');
- is ($one->error, 'keytab unchanging support not configured',
- ' with the right error');
- $Wallet::Config::KEYTAB_REMCTL_CACHE = 'krb5cc_test';
- is ($one->get (@trace), undef, ' and still fails without host');
- is ($one->error, 'keytab unchanging support not configured',
- ' with the right error');
- $Wallet::Config::KEYTAB_REMCTL_HOST = 'localhost';
- $Wallet::Config::KEYTAB_REMCTL_PRINCIPAL = $principal;
- $Wallet::Config::KEYTAB_REMCTL_PORT = 14373;
- is ($one->get (@trace), undef, ' and still fails without ACL');
- is ($one->error,
- "cannot retrieve keytab for wallet/one\@$realm: Access denied",
- ' with the right error');
- open (ACL, '>', 'test-acl') or die "cannot create test-acl: $!\n";
- print ACL "$principal\n";
- close ACL;
- is ($one->get (@trace), 'Keytab for wallet/one', 'Now get works');
- is ($ENV{KRB5CCNAME}, 'krb5cc_good',
- ' and we did not nuke the cache name');
- is ($two->get (@trace), undef, ' but get for wallet/two does not');
- is ($two->error,
- "cannot retrieve keytab for wallet/two\@$realm: bite me",
- ' with the right error');
- is ($one->destroy (@trace), 1, 'Destroying wallet/one works');
- is ($two->destroy (@trace), 1, ' as does destroying wallet/two');
- remctld_stop;
+ # Now Heimdal. Since the keytab contains timestamps, before testing for
+ # equality we have to substitute out the timestamps.
+ SKIP: {
+ skip 'skipping Heimdal unchanging tests for MIT', 10
+ if (lc ($Wallet::Config::KEYTAB_KRBTYPE) eq 'mit');
+ my $data = $one->get (@trace);
+ ok (defined $data, 'Get of unchanging keytab works');
+ ok (keytab_valid ($data, 'wallet/one'), ' and the keytab is valid');
+ my $second = $one->get (@trace);
+ ok (defined $second, ' and second retrieval also works');
+ $data =~ s/one.{8}/one\000\000\000\000\000\000\000\000/g;
+ $second =~ s/one.{8}/one\000\000\000\000\000\000\000\000/g;
+ is ($data, $second, ' and the keytab matches');
+ is ($one->flag_clear ('unchanging', @trace), 1,
+ 'Clearing the unchanging flag works');
+ $data = $one->get (@trace);
+ ok (defined ($data), ' and getting the keytab works');
+ ok (keytab_valid ($data, 'wallet/one'), ' and the keytab is valid');
+ $data =~ s/one.{8}/one\000\000\000\000\000\000\000\000/g;
+ ok ($data ne $second, ' and the new keytab is different');
+ is ($one->destroy (@trace), 1, 'Destroying wallet/one works');
+ is ($two->destroy (@trace), 1, ' as does destroying wallet/two');
+ }
# Check that history has been updated correctly.
$history .= <<"EOO";
@@ -426,61 +479,30 @@ $date set flag unchanging
by $user from $host
$date get
by $user from $host
+$date get
+ by $user from $host
+$date clear flag unchanging
+ by $user from $host
+$date get
+ by $user from $host
$date destroy
by $user from $host
EOO
is ($one->history, $history, 'History is correct to this point');
}
-# Tests for kaserver synchronization support.
+# Tests for synchronization support. This code is deactivated at present
+# since no synchronization targets are supported, but we want to still test
+# the basic stub code.
SKIP: {
- skip 'no keytab configuration', 106 unless -f 't/data/test.keytab';
+ skip 'no keytab configuration', 18 unless -f 't/data/test.keytab';
- # Test the principal mapping. We can do this without having a kaserver
- # configuration. We only need a basic keytab object configuration. Do
- # this as white-box testing since we don't want to fill the test realm
- # with a bunch of random principals.
+ # Test setting synchronization attributes, which can also be done without
+ # configuration.
my $one = eval {
Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace)
};
ok (defined ($one), 'Creating wallet/one succeeds');
- my %princs =
- (foo => 'foo',
- host => 'host',
- rcmd => 'rcmd',
- 'rcmd.foo' => 'rcmd.foo',
- 'host/foo.example.org' => 'rcmd.foo',
- 'ident/foo.example.org' => 'ident.foo',
- 'imap/foo.example.org' => 'imap.foo',
- 'pop/foo.example.org' => 'pop.foo',
- 'smtp/foo.example.org' => 'smtp.foo',
- 'service/foo' => 'service.foo',
- 'foo/bar' => 'foo.bar');
- for my $princ (sort keys %princs) {
- my $result = $princs{$princ};
- is ($one->kaserver_name ($princ), $result, "Name mapping: $princ");
- is ($one->kaserver_name ("$princ\@EXAMPLE.ORG"), $result,
- ' with K5 realm');
- $Wallet::Config::KEYTAB_AFS_REALM = 'AFS.EXAMPLE.ORG';
- is ($one->kaserver_name ($princ), "$result\@AFS.EXAMPLE.ORG",
- ' with K4 realm');
- is ($one->kaserver_name ("$princ\@EXAMPLE.ORG"),
- "$result\@AFS.EXAMPLE.ORG", ' with K5 and K4 realm');
- undef $Wallet::Config::KEYTAB_AFS_REALM;
- }
- for my $princ (qw{service/foo/bar foo/bar/baz}) {
- is ($one->kaserver_name ($princ), undef, "Name mapping: $princ");
- is ($one->kaserver_name ("$princ\@EXAMPLE.ORG"), undef,
- ' with K5 realm');
- $Wallet::Config::KEYTAB_AFS_REALM = 'AFS.EXAMPLE.ORG';
- is ($one->kaserver_name ($princ), undef, ' with K4 realm');
- is ($one->kaserver_name ("$princ\@EXAMPLE.ORG"), undef,
- ' with K5 and K4 realm');
- undef $Wallet::Config::KEYTAB_AFS_REALM;
- }
-
- # Test setting synchronization attributes, which can also be done without
- # configuration.
my $expected = <<"EOO";
Type: keytab
Name: wallet/one
@@ -495,16 +517,20 @@ EOO
my @targets = $one->attr ('foo');
is (scalar (@targets), 0, ' and getting an unknown attribute fails');
is ($one->error, 'unknown attribute foo', ' with the right error');
- is ($one->attr ('sync', [ 'foo' ], @trace), undef,
+ is ($one->attr ('sync', [ 'kaserver' ], @trace), undef,
' and setting an unknown sync target fails');
- is ($one->error, 'unsupported synchronization target foo',
+ is ($one->error, 'unsupported synchronization target kaserver',
' with the right error');
is ($one->attr ('sync', [ 'kaserver', 'bar' ], @trace), undef,
' and setting two targets fails');
is ($one->error, 'only one synchronization target supported',
' with the right error');
- is ($one->attr ('sync', [ 'kaserver' ], @trace), 1,
- ' but setting only kaserver works');
+
+ # Create a synchronization manually so that we can test the display and
+ # removal code.
+ my $sql = "insert into keytab_sync (ks_name, ks_target) values
+ ('wallet/one', 'kaserver')";
+ $dbh->do ($sql);
@targets = $one->attr ('sync');
is (scalar (@targets), 1, ' and now one target is set');
is ($targets[0], 'kaserver', ' and it is correct');
@@ -521,15 +547,10 @@ EOO
$history .= <<"EOO";
$date create
by $user from $host
-$date add kaserver to attribute sync
- by $user from $host
EOO
is ($one->history, $history, ' and history is correct for attributes');
- is ($one->destroy (@trace), undef, 'Destroying wallet/one fails');
- is ($one->error, 'kaserver synchronization not configured',
- ' because kaserver support is not configured');
is ($one->attr ('sync', [], @trace), 1,
- ' but removing the kaserver sync attribute works');
+ 'Removing the kaserver sync attribute works');
is ($one->destroy (@trace),1, ' and then destroying wallet/one works');
$history .= <<"EOO";
$date remove kaserver from attribute sync
@@ -537,135 +558,7 @@ $date remove kaserver from attribute sync
$date destroy
by $user from $host
EOO
-
- # Set up our configuration.
- skip 'no AFS kaserver configuration', 34 unless -f 't/data/test.srvtab';
- skip 'no kaserver support', 34 unless -x '../kasetkey/kasetkey';
- $Wallet::Config::KEYTAB_FILE = 't/data/test.keytab';
- $Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal');
- $Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm');
- $Wallet::Config::KEYTAB_TMP = '.';
- $Wallet::Config::KEYTAB_AFS_KASETKEY = '../kasetkey/kasetkey';
- my $realm = $Wallet::Config::KEYTAB_REALM;
- my $k5 = "wallet/one\@$realm";
-
- # Recreate and reconfigure the object.
- $one = eval {
- Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace)
- };
- ok (defined ($one), 'Creating wallet/one succeeds');
- is ($one->attr ('sync', [ 'kaserver' ], @trace), 1,
- ' and setting the kaserver sync attribute works');
-
- # Finally, we can test.
- is ($one->get (@trace), undef, 'Get without configuration fails');
- is ($one->error, 'kaserver synchronization not configured',
- ' with the right error');
- $Wallet::Config::KEYTAB_AFS_ADMIN = contents ('t/data/test.admin');
- my $k4_realm = $Wallet::Config::KEYTAB_AFS_ADMIN;
- $k4_realm =~ s/^[^\@]+\@//;
- $Wallet::Config::KEYTAB_AFS_REALM = $k4_realm;
- my $k4 = "wallet.one\@$k4_realm";
- is ($one->get (@trace), undef, ' and still fails with just admin');
- is ($one->error, 'kaserver synchronization not configured',
- ' with the right error');
- $Wallet::Config::KEYTAB_AFS_SRVTAB = 't/data/test.srvtab';
- my $keytab = $one->get (@trace);
- if (defined ($keytab)) {
- ok (1, ' and now get works');
- } else {
- is ($one->error, '', ' and now get works');
- }
- ok (valid_srvtab ($one, $keytab, $k5, $k4), ' and the srvtab is valid');
- ok (! -f "./srvtab.$$", ' and the temporary file was cleaned up');
-
- # Now remove the sync attribute and make sure things aren't synced.
- is ($one->attr ('sync', [], @trace), 1, 'Clearing sync works');
- @targets = $one->attr ('sync');
- is (scalar (@targets), 0, ' and now there is no attribute');
- is ($one->error, undef, ' and no error');
- my $new_keytab = $one->get (@trace);
- ok (defined ($new_keytab), ' and get still works');
- ok (! valid_srvtab ($one, $new_keytab, $k5, $k4),
- ' but the srvtab does not');
- ok (valid_srvtab ($one, $keytab, $k5, $k4), ' and the old one does');
- is ($one->destroy (@trace), 1, ' and destroying wallet/one works');
- ok (valid_srvtab ($one, $keytab, $k5, $k4),
- ' and the principal is still there');
-
- # Test KEYTAB_AFS_DESTROY.
- $one = eval {
- Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace)
- };
- ok (defined ($one), 'Creating wallet/one succeeds');
- $Wallet::Config::KEYTAB_AFS_DESTROY = 1;
- $new_keytab = $one->get (@trace);
- ok (defined ($new_keytab), ' and get works');
- ok (! valid_srvtab ($one, $new_keytab, $k5, $k4),
- ' but the srvtab does not');
- ok (! valid_srvtab ($one, $keytab, $k5, $k4),
- ' and now neither does the old one');
- $Wallet::Config::KEYTAB_AFS_DESTROY = 0;
-
- # Put it back and make sure it works again.
- is ($one->attr ('sync', [ 'kaserver' ], @trace), 1, 'Setting sync works');
- $keytab = $one->get (@trace);
- ok (defined ($keytab), ' and get works');
- ok (valid_srvtab ($one, $keytab, $k5, $k4), ' and the srvtab is valid');
- $Wallet::Config::KEYTAB_AFS_KASETKEY = '/path/to/nonexistent/file';
- $new_keytab = $one->get (@trace);
- ok (! defined ($new_keytab),
- ' but it fails if we mess up the kasetkey path');
- like ($one->error, qr{^cannot synchronize key with kaserver: },
- ' with the right error message');
- ok (! -f "keytab.$$", ' and the temporary file was cleaned up');
- $Wallet::Config::KEYTAB_AFS_KASETKEY = '../kasetkey/kasetkey';
-
- # Destroy the principal and recreate it and make sure we cleaned up.
- is ($one->destroy (@trace), 1, 'Destroying wallet/one works');
- ok (! valid_srvtab ($one, $keytab, $k5, $k4),
- ' and the principal is gone');
- $one = eval {
- Wallet::Object::Keytab->create ('keytab', 'wallet/one', $dbh, @trace)
- };
- ok (defined ($one), ' and recreating it succeeds');
- @targets = $one->attr ('sync');
- is (scalar (@targets), 0, ' and now there is no attribute');
- is ($one->error, undef, ' and no error');
-
- # Now destroy it for good.
- is ($one->destroy (@trace), 1, 'Destroying wallet/one works');
-
- # Check that history is still correct.
- $history .= <<"EOO";
-$date create
- by $user from $host
-$date add kaserver to attribute sync
- by $user from $host
-$date get
- by $user from $host
-$date remove kaserver from attribute sync
- by $user from $host
-$date get
- by $user from $host
-$date destroy
- by $user from $host
-$date create
- by $user from $host
-$date get
- by $user from $host
-$date add kaserver to attribute sync
- by $user from $host
-$date get
- by $user from $host
-$date destroy
- by $user from $host
-$date create
- by $user from $host
-$date destroy
- by $user from $host
-EOO
- is ($one->history, $history, 'History is correct to this point');
+ is ($one->history, $history, ' and history is correct for removal');
}
# Tests for enctype restriction.
@@ -676,6 +569,7 @@ SKIP: {
$Wallet::Config::KEYTAB_FILE = 't/data/test.keytab';
$Wallet::Config::KEYTAB_PRINCIPAL = contents ('t/data/test.principal');
$Wallet::Config::KEYTAB_REALM = contents ('t/data/test.realm');
+ $Wallet::Config::KEYTAB_KRBTYPE = contents ('t/data/test.krbtype');
$Wallet::Config::KEYTAB_TMP = '.';
my $realm = $Wallet::Config::KEYTAB_REALM;
my $principal = $Wallet::Config::KEYTAB_PRINCIPAL;
@@ -742,8 +636,7 @@ EOO
'Setting an unrecognized enctype fails');
is ($one->error, 'unknown encryption type foo-bar',
' with the right error message');
- @values = enctypes ($keytab);
- is ("@values", "@enctypes", ' and we did rollback properly');
+ is ($one->show, $expected, ' and we did rollback properly');
$history .= <<"EOO";
$date get
by $user from $host
@@ -753,6 +646,7 @@ EOO
# Now, try testing limiting the enctypes to just one.
SKIP: {
skip 'insufficient recognized enctypes', 14 unless @enctypes > 1;
+
is ($one->attr ('enctypes', [ $enctypes[0] ], @trace), 1,
'Setting a single enctype works');
for my $enctype (@enctypes) {
@@ -764,8 +658,12 @@ EOO
is ("@values", $enctypes[0], ' and we get back the right value');
$keytab = $one->get (@trace);
ok (defined ($keytab), ' and retrieving the keytab still works');
- @values = enctypes ($keytab);
- is ("@values", $enctypes[0], ' and it has the right enctype');
+ if (defined ($keytab)) {
+ @values = enctypes ($keytab);
+ is ("@values", $enctypes[0], ' and it has the right enctype');
+ } else {
+ ok (0, ' and it has the right keytab');
+ }
is ($one->attr ('enctypes', [ $enctypes[1] ], @trace), 1,
'Setting a different single enctype works');
@values = $one->attr ('enctypes');
diff --git a/perl/t/lib/Util.pm b/perl/t/lib/Util.pm
index a1bacbd..ab88b39 100644
--- a/perl/t/lib/Util.pm
+++ b/perl/t/lib/Util.pm
@@ -1,5 +1,4 @@
# Util -- Utility class for wallet tests.
-# $Id$
#
# Written by Russ Allbery <rra@stanford.edu>
# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
@@ -21,7 +20,8 @@ $VERSION = '0.02';
use Exporter ();
@ISA = qw(Exporter);
-@EXPORT = qw(contents db_setup getcreds remctld_spawn remctld_stop);
+@EXPORT = qw(contents db_setup getcreds keytab_valid remctld_spawn
+ remctld_stop);
##############################################################################
# General utility functions
@@ -67,7 +67,7 @@ sub db_setup {
}
##############################################################################
-# Local ticket cache
+# Kerberos utility functions
##############################################################################
# Given a keytab file and a principal, try authenticating with kinit.
@@ -86,6 +86,22 @@ sub getcreds {
return 0;
}
+# Given keytab data and the principal, write it to a file and try
+# authenticating using kinit.
+sub keytab_valid {
+ my ($keytab, $principal) = @_;
+ open (KEYTAB, '>', 'keytab') or die "cannot create keytab: $!\n";
+ print KEYTAB $keytab;
+ close KEYTAB;
+ $principal .= '@' . $Wallet::Config::KEYTAB_REALM
+ unless $principal =~ /\@/;
+ my $result = getcreds ('keytab', $principal);
+ if ($result) {
+ unlink 'keytab';
+ }
+ return $result;
+}
+
##############################################################################
# remctld handling
##############################################################################
diff --git a/perl/t/object.t b/perl/t/object.t
index 94fe22b..46e67e5 100755
--- a/perl/t/object.t
+++ b/perl/t/object.t
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/object.t -- Tests for the basic object implementation.
#
@@ -256,11 +255,11 @@ ok (defined ($object), 'Recreating the object succeeds');
$output = <<"EOO";
$date create
by $user from $host
-$date set owner to 1
+$date set owner to ADMIN (1)
by $user from $host
-$date unset owner (was 1)
+$date unset owner (was ADMIN (1))
by $user from $host
-$date set owner to 1
+$date set owner to ADMIN (1)
by $user from $host
$date set expires to $now
by $user from $host
@@ -268,35 +267,35 @@ $date unset expires (was $now)
by $user from $host
$date set expires to $now
by $user from $host
-$date set acl_get to 1
+$date set acl_get to ADMIN (1)
by $user from $host
-$date unset acl_get (was 1)
+$date unset acl_get (was ADMIN (1))
by $user from $host
-$date set acl_get to 1
+$date set acl_get to ADMIN (1)
by $user from $host
-$date set acl_store to 1
+$date set acl_store to ADMIN (1)
by $user from $host
-$date unset acl_store (was 1)
+$date unset acl_store (was ADMIN (1))
by $user from $host
-$date set acl_store to 1
+$date set acl_store to ADMIN (1)
by $user from $host
-$date set acl_show to 1
+$date set acl_show to ADMIN (1)
by $user from $host
-$date unset acl_show (was 1)
+$date unset acl_show (was ADMIN (1))
by $user from $host
-$date set acl_show to 1
+$date set acl_show to ADMIN (1)
by $user from $host
-$date set acl_destroy to 1
+$date set acl_destroy to ADMIN (1)
by $user from $host
-$date unset acl_destroy (was 1)
+$date unset acl_destroy (was ADMIN (1))
by $user from $host
-$date set acl_destroy to 1
+$date set acl_destroy to ADMIN (1)
by $user from $host
-$date set acl_flags to 1
+$date set acl_flags to ADMIN (1)
by $user from $host
-$date unset acl_flags (was 1)
+$date unset acl_flags (was ADMIN (1))
by $user from $host
-$date set acl_flags to 1
+$date set acl_flags to ADMIN (1)
by $user from $host
$date set flag locked
by $user from $host
diff --git a/perl/t/pod-spelling.t b/perl/t/pod-spelling.t
new file mode 100755
index 0000000..d3ab858
--- /dev/null
+++ b/perl/t/pod-spelling.t
@@ -0,0 +1,75 @@
+#!/usr/bin/perl -w
+#
+# Check for spelling errors in POD documentation
+#
+# Checks all POD files in the tree for spelling problems using Pod::Spell and
+# either aspell or ispell. aspell is preferred. This test is disabled unless
+# RRA_MAINTAINER_TESTS is set, since spelling dictionaries vary too much
+# between environments.
+#
+# Copyright 2008, 2009 Russ Allbery <rra@stanford.edu>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+use strict;
+use Test::More;
+
+# Skip all spelling tests unless the maintainer environment variable is set.
+plan skip_all => 'Spelling tests only run for maintainer'
+ unless $ENV{RRA_MAINTAINER_TESTS};
+
+# Load required Perl modules.
+eval 'use Test::Pod 1.00';
+plan skip_all => 'Test::Pod 1.00 required for testing POD' if $@;
+eval 'use Pod::Spell';
+plan skip_all => 'Pod::Spell required to test POD spelling' if $@;
+
+# Locate a spell-checker. hunspell is not currently supported due to its lack
+# of support for contractions (at least in the version in Debian).
+my @spell;
+my %options = (aspell => [ qw(-d en_US --home-dir=./ list) ],
+ ispell => [ qw(-d american -l -p /dev/null) ]);
+SEARCH: for my $program (qw/aspell ispell/) {
+ for my $dir (split ':', $ENV{PATH}) {
+ if (-x "$dir/$program") {
+ @spell = ("$dir/$program", @{ $options{$program} });
+ }
+ last SEARCH if @spell;
+ }
+}
+plan skip_all => 'aspell or ispell required to test POD spelling'
+ unless @spell;
+
+# Prerequisites are satisfied, so we're going to do some testing. Figure out
+# what POD files we have and from that develop our plan.
+$| = 1;
+my @pod = all_pod_files ();
+plan tests => scalar @pod;
+
+# Finally, do the checks.
+for my $pod (@pod) {
+ my $child = open (CHILD, '-|');
+ if (not defined $child) {
+ die "Cannot fork: $!\n";
+ } elsif ($child == 0) {
+ my $pid = open (SPELL, '|-', @spell) or die "Cannot run @spell: $!\n";
+ open (POD, '<', $pod) or die "Cannot open $pod: $!\n";
+ my $parser = Pod::Spell->new;
+ $parser->parse_from_filehandle (\*POD, \*SPELL);
+ close POD;
+ close SPELL;
+ exit ($? >> 8);
+ } else {
+ my @words = <CHILD>;
+ close CHILD;
+ SKIP: {
+ skip "@spell failed for $pod", 1 unless $? == 0;
+ for (@words) {
+ s/^\s+//;
+ s/\s+$//;
+ }
+ is ("@words", '', $pod);
+ }
+ }
+}
diff --git a/perl/t/pod.t b/perl/t/pod.t
index da4d0d3..c467b82 100755
--- a/perl/t/pod.t
+++ b/perl/t/pod.t
@@ -1,17 +1,14 @@
-#!/usr/bin/perl
-# $Id$
+#!/usr/bin/perl -w
#
-# t/pod.t -- Test POD formatting for the wallet Perl modules.
+# Test POD formatting for the wallet Perl modules.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
+use strict;
+use Test::More;
eval 'use Test::Pod 1.00';
-if ($@) {
- print "1..1\n";
- print "ok 1 # skip - Test::Pod 1.00 required for testing POD\n";
- exit;
-}
+plan skip_all => 'Test::Pod 1.00 required for testing POD' if $@;
all_pod_files_ok ();
diff --git a/perl/t/report.t b/perl/t/report.t
new file mode 100755
index 0000000..a18b995
--- /dev/null
+++ b/perl/t/report.t
@@ -0,0 +1,171 @@
+#!/usr/bin/perl -w
+#
+# t/report.t -- Tests for the wallet reporting interface.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+use Test::More tests => 83;
+
+use Wallet::Admin;
+use Wallet::Report;
+use Wallet::Server;
+
+use lib 't/lib';
+use Util;
+
+# Use Wallet::Admin to set up the database.
+db_setup;
+my $admin = eval { Wallet::Admin->new };
+is ($@, '', 'Wallet::Admin creation did not die');
+is ($admin->reinitialize ('admin@EXAMPLE.COM'), 1,
+ 'Database initialization succeeded');
+$admin->register_object ('base', 'Wallet::Object::Base');
+$admin->register_verifier ('base', 'Wallet::ACL::Base');
+
+# We have an empty database, so we should see no objects and one ACL.
+my $report = eval { Wallet::Report->new };
+is ($@, '', 'Wallet::Report creation did not die');
+ok ($report->isa ('Wallet::Report'), ' and returned the right class');
+my @objects = $report->objects;
+is (scalar (@objects), 0, 'No objects in the database');
+is ($report->error, undef, ' and no error');
+my @acls = $report->acls;
+is (scalar (@acls), 1, 'One ACL in the database');
+is ($acls[0][0], 1, ' and that is ACL ID 1');
+is ($acls[0][1], 'ADMIN', ' with the right name');
+
+# Create an object.
+$server = eval { Wallet::Server->new ('admin@EXAMPLE.COM', 'localhost') };
+is ($@, '', 'Creating a server instance did not die');
+is ($server->create ('base', 'service/admin'), 1,
+ ' and creating base:service/admin succeeds');
+
+# Now, we should see one object.
+@objects = $report->objects;
+is (scalar (@objects), 1, ' and now there is one object');
+is ($objects[0][0], 'base', ' with the right type');
+is ($objects[0][1], 'service/admin', ' and the right name');
+
+# Create another ACL.
+is ($server->acl_create ('first'), 1, 'ACL creation succeeds');
+@acls = $report->acls;
+is (scalar (@acls), 2, ' and now there are two ACLs');
+is ($acls[0][0], 1, ' and the first ID is correct');
+is ($acls[0][1], 'ADMIN', ' and the first name is correct');
+is ($acls[1][0], 2, ' and the second ID is correct');
+is ($acls[1][1], 'first', ' and the second name is correct');
+
+# Delete that ACL and create another.
+is ($server->acl_create ('second'), 1, 'Second ACL creation succeeds');
+is ($server->acl_destroy ('first'), 1, ' and deletion of the first succeeds');
+@acls = $report->acls;
+is (scalar (@acls), 2, ' and there are still two ACLs');
+is ($acls[0][0], 1, ' and the first ID is still the same');
+is ($acls[0][1], 'ADMIN', ' and the first name is still the same');
+is ($acls[1][0], 3, ' but the second ID has changed');
+is ($acls[1][1], 'second', ' and the second name is correct');
+
+# Currently, we have no owners, so we should get an empty owner report.
+my @lines = $report->owners ('%', '%');
+is (scalar (@lines), 0, 'Owner report is currently empty');
+is ($report->error, undef, ' and there is no error');
+
+# Set an owner and make sure we now see something in the report.
+is ($server->owner ('base', 'service/admin', 'ADMIN'), 1,
+ 'Setting an owner works');
+@lines = $report->owners ('%', '%');
+is (scalar (@lines), 1, ' and now there is one owner in the report');
+is ($lines[0][0], 'krb5', ' with the right scheme');
+is ($lines[0][1], 'admin@EXAMPLE.COM', ' and the right identifier');
+@lines = $report->owners ('keytab', '%');
+is (scalar (@lines), 0, 'Owners of keytabs is empty');
+is ($report->error, undef, ' with no error');
+@lines = $report->owners ('base', 'foo/%');
+is (scalar (@lines), 0, 'Owners of base foo/* objects is empty');
+is ($report->error, undef, ' with no error');
+
+# Create a second object with the same owner.
+is ($server->create ('base', 'service/foo'), 1,
+ 'Creating base:service/foo succeeds');
+is ($server->owner ('base', 'service/foo', 'ADMIN'), 1,
+ ' and setting the owner to the same value works');
+@lines = $report->owners ('base', 'service/%');
+is (scalar (@lines), 1, ' and there is still owner in the report');
+is ($lines[0][0], 'krb5', ' with the right scheme');
+is ($lines[0][1], 'admin@EXAMPLE.COM', ' and the right identifier');
+
+# Change the owner of the second object to an empty ACL.
+is ($server->owner ('base', 'service/foo', 'second'), 1,
+ ' and changing the owner to an empty ACL works');
+@lines = $report->owners ('base', '%');
+is (scalar (@lines), 1, ' and there is still owner in the report');
+is ($lines[0][0], 'krb5', ' with the right scheme');
+is ($lines[0][1], 'admin@EXAMPLE.COM', ' and the right identifier');
+
+# Add a few things to the second ACL to see what happens.
+is ($server->acl_add ('second', 'base', 'foo'), 1,
+ 'Adding an ACL line to the new ACL works');
+is ($server->acl_add ('second', 'base', 'bar'), 1,
+ ' and adding another ACL line to the new ACL works');
+@lines = $report->owners ('base', '%');
+is (scalar (@lines), 3, ' and now there are three owners in the report');
+is ($lines[0][0], 'base', ' first has the right scheme');
+is ($lines[0][1], 'bar', ' and the right identifier');
+is ($lines[1][0], 'base', ' second has the right scheme');
+is ($lines[1][1], 'foo', ' and the right identifier');
+is ($lines[2][0], 'krb5', ' third has the right scheme');
+is ($lines[2][1], 'admin@EXAMPLE.COM', ' and the right identifier');
+
+# Test ownership and other ACL values. Change one keytab to be not owned by
+# ADMIN, but have group permission on it. We'll need a third object neither
+# owned by ADMIN or with any permissions from it.
+is ($server->create ('base', 'service/null'), 1,
+ 'Creating base:service/null succeeds');
+is ($server->acl ('base', 'service/foo', 'get', 'ADMIN'), 1,
+ 'Changing the get ACL for the search also does');
+@lines = $report->objects ('owner', 'ADMIN');
+is (scalar (@lines), 1, 'Searching for objects owned by ADMIN finds one');
+is ($lines[0][0], 'base', ' and it has the right type');
+is ($lines[0][1], 'service/admin', ' and the right name');
+@lines = $report->objects ('owner', 'null');
+is (scalar (@lines), 1, 'Searching for objects with no set ownerfinds one');
+is ($lines[0][0], 'base', ' and it has the right type');
+is ($lines[0][1], 'service/null', ' and the right name');
+@lines = $report->objects ('acl', 'ADMIN');
+is (scalar (@lines), 2, 'ADMIN has any rights at all on two objects');
+is ($lines[0][0], 'base', ' and the first has the right type');
+is ($lines[0][1], 'service/admin', ' and the right name');
+is ($lines[1][0], 'base', ' and the second has the right type');
+is ($lines[1][1], 'service/foo', ' and the right name');
+
+# Listing objects of a specific type.
+@lines = $report->objects ('type', 'base');
+is (scalar (@lines), 3, 'Searching for all objects of type base finds three');
+is ($lines[0][0], 'base', ' and the first has the right type');
+is ($lines[0][1], 'service/admin', ' and the right name');
+is ($lines[1][0], 'base', ' and the second has the right type');
+is ($lines[1][1], 'service/foo', ' and the right name');
+is ($lines[2][0], 'base', ' and the third has the right type');
+is ($lines[2][1], 'service/null', ' and the right name');
+@lines = $report->objects ('type', 'keytab');
+is (scalar (@lines), 0, 'Searching for all objects of type keytab finds none');
+
+# Test setting a flag, searching for objects with it, and then clearing it.
+is ($server->flag_set ('base', 'service/admin', 'unchanging'), 1,
+ 'Setting a flag works');
+@lines = $report->objects ('flag', 'unchanging');
+is (scalar (@lines), 1, 'Searching for all objects with that flag finds one');
+is ($lines[0][0], 'base', ' and it has the right type');
+is ($lines[0][1], 'service/admin', ' and the right name');
+is ($server->flag_clear ('base', 'service/admin', 'unchanging'), 1,
+ 'Clearing the flag works');
+@lines = $report->objects ('flag', 'unchanging');
+is (scalar (@lines), 0, ' and now there are no objects in the report');
+is ($report->error, undef, ' with no error');
+
+# Clean up.
+$admin->destroy;
+unlink 'wallet-db';
diff --git a/perl/t/schema.t b/perl/t/schema.t
index c7e9133..559ece4 100755
--- a/perl/t/schema.t
+++ b/perl/t/schema.t
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/schema.t -- Tests for the wallet schema class.
#
@@ -22,7 +21,7 @@ ok (defined $schema, 'Wallet::Schema creation');
ok ($schema->isa ('Wallet::Schema'), ' and class verification');
my @sql = $schema->sql;
ok (@sql > 0, 'sql() returns something');
-is (scalar (@sql), 29, ' and returns the right number of statements');
+is (scalar (@sql), 28, ' and returns the right number of statements');
# Connect to a database and test create.
db_setup;
diff --git a/perl/t/server.t b/perl/t/server.t
index 08edd56..090387b 100755
--- a/perl/t/server.t
+++ b/perl/t/server.t
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/server.t -- Tests for the wallet server API.
#
@@ -398,31 +397,31 @@ DATE set expires to $now
by $admin from $host
DATE unset expires (was $now)
by $admin from $host
-DATE set acl_get to 1
+DATE set acl_get to ADMIN (1)
by $admin from $host
-DATE unset acl_get (was 1)
+DATE unset acl_get (was ADMIN (1))
by $admin from $host
-DATE set acl_store to 1
+DATE set acl_store to ADMIN (1)
by $admin from $host
-DATE unset acl_store (was 1)
+DATE unset acl_store (was ADMIN (1))
by $admin from $host
-DATE set owner to 1
+DATE set owner to ADMIN (1)
by $admin from $host
-DATE set acl_get to 5
+DATE set acl_get to empty (5)
by $admin from $host
-DATE set acl_store to 5
+DATE set acl_store to empty (5)
by $admin from $host
-DATE unset acl_store (was 5)
+DATE unset acl_store (was empty (5))
by $admin from $host
-DATE unset owner (was 1)
+DATE unset owner (was ADMIN (1))
by $admin from $host
-DATE set owner to 1
+DATE set owner to ADMIN (1)
by $admin from $host
DATE set flag locked
by $admin from $host
DATE clear flag locked
by $admin from $host
-DATE unset owner (was 1)
+DATE unset owner (was ADMIN (1))
by $admin from $host
DATE set flag unchanging
by $admin from $host
@@ -528,7 +527,7 @@ is ($show, $expected, ' and show an object we own');
$history = <<"EOO";
DATE create
by $admin from $host
-DATE set owner to 2
+DATE set owner to user1 (2)
by $admin from $host
EOO
$seen = $server->history ('base', 'service/user1');
@@ -609,13 +608,13 @@ is ($show, $expected, ' and show an object we jointly own');
$history = <<"EOO";
DATE create
by $admin from $host
-DATE set owner to 4
+DATE set owner to both (4)
by $admin from $host
-DATE set acl_show to 2
+DATE set acl_show to user1 (2)
by $admin from $host
-DATE set acl_destroy to 3
+DATE set acl_destroy to user2 (3)
by $admin from $host
-DATE set acl_flags to 2
+DATE set acl_flags to user1 (2)
by $admin from $host
DATE set flag unchanging
by $user1 from $host
@@ -680,7 +679,7 @@ is ($show, $expected, ' and show an object we own');
$history = <<"EOO";
DATE create
by $admin from $host
-DATE set owner to 3
+DATE set owner to user2 (3)
by $admin from $host
EOO
$seen = $server->history ('base', 'service/user2');
diff --git a/perl/t/verifier-netdb.t b/perl/t/verifier-netdb.t
index 6a77e3c..dcbbdd8 100755
--- a/perl/t/verifier-netdb.t
+++ b/perl/t/verifier-netdb.t
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/verifier-netdb.t -- Tests for the NetDB wallet ACL verifiers.
#
diff --git a/perl/t/verifier.t b/perl/t/verifier.t
index 96e641d..3243d9c 100755
--- a/perl/t/verifier.t
+++ b/perl/t/verifier.t
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id$
#
# t/verifier.t -- Tests for the basic wallet ACL verifiers.
#
diff --git a/portable/asprintf.c b/portable/asprintf.c
index 9cae827..4219a19 100644
--- a/portable/asprintf.c
+++ b/portable/asprintf.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Replacement for a missing asprintf and vasprintf.
*
* Provides the same functionality as the standard GNU library routines
@@ -19,7 +18,8 @@
#if TESTING
# define asprintf test_asprintf
# define vasprintf test_vasprintf
-int test_asprintf(char **, const char *, ...);
+int test_asprintf(char **, const char *, ...)
+ __attribute__((__format__(printf, 2, 3)));
int test_vasprintf(char **, const char *, va_list);
#endif
diff --git a/portable/dummy.c b/portable/dummy.c
index 66341c3..8a0d54d 100644
--- a/portable/dummy.c
+++ b/portable/dummy.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Dummy symbol to prevent an empty library.
*
* On platforms that already have all of the functions that libportable would
diff --git a/portable/krb5-extra.c b/portable/krb5-extra.c
new file mode 100644
index 0000000..afd00e8
--- /dev/null
+++ b/portable/krb5-extra.c
@@ -0,0 +1,125 @@
+/*
+ * Portability glue functions for Kerberos.
+ *
+ * This file provides definitions of the interfaces that portable/krb5.h
+ * ensures exist if the function wasn't available in the Kerberos libraries.
+ * Everything in this file will be protected by #ifndef. If the native
+ * Kerberos libraries are fully capable, this file will be skipped.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * This work is hereby placed in the public domain by its author.
+ */
+
+#include <config.h>
+#include <portable/krb5.h>
+#include <portable/system.h>
+
+#include <errno.h>
+
+/* Figure out what header files to include for error reporting. */
+#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) && !defined(HAVE_KRB5_GET_ERR_TEXT)
+# if !defined(HAVE_KRB5_GET_ERROR_STRING)
+# if defined(HAVE_IBM_SVC_KRB5_SVC_H)
+# include <ibm_svc/krb5_svc.h>
+# elif defined(HAVE_ET_COM_ERR_H)
+# include <et/com_err.h>
+# else
+# include <com_err.h>
+# endif
+# endif
+#endif
+
+/* Used for unused parameters to silence gcc warnings. */
+#define UNUSED __attribute__((__unused__))
+
+/*
+ * This string is returned for unknown error messages. We use a static
+ * variable so that we can be sure not to free it.
+ */
+static const char error_unknown[] = "unknown error";
+
+
+#ifndef HAVE_KRB5_GET_ERROR_MESSAGE
+/*
+ * Given a Kerberos error code, return the corresponding error. Prefer the
+ * Kerberos interface if available since it will provide context-specific
+ * error information, whereas the error_message() call will only provide a
+ * fixed message.
+ */
+const char *
+krb5_get_error_message(krb5_context ctx UNUSED, krb5_error_code code UNUSED)
+{
+ const char *msg = NULL;
+
+# if defined(HAVE_KRB5_GET_ERROR_STRING)
+ msg = krb5_get_error_string(ctx);
+# elif defined(HAVE_KRB5_GET_ERR_TEXT)
+ msg = krb5_get_err_text(ctx, code);
+# elif defined(HAVE_KRB5_SVC_GET_MSG)
+ krb5_svc_get_msg(code, (char **) &msg);
+# else
+ msg = error_message(code);
+# endif
+ if (msg == NULL)
+ return error_unknown;
+ else
+ return msg;
+}
+#endif /* !HAVE_KRB5_GET_ERROR_MESSAGE */
+
+
+#ifndef HAVE_KRB5_FREE_ERROR_MESSAGE
+/*
+ * Free an error string if necessary. If we returned a static string, make
+ * sure we don't free it.
+ *
+ * This code assumes that the set of implementations that have
+ * krb5_free_error_message is a subset of those with krb5_get_error_message.
+ * If this assumption ever breaks, we may call the wrong free function.
+ */
+static void
+krb5_free_error_message(krb5_context ctx UNUSED, const char *msg)
+{
+ if (msg == error_unknown)
+ return;
+# if defined(HAVE_KRB5_GET_ERROR_STRING)
+ krb5_free_error_string(ctx, (char *) msg);
+# elif defined(HAVE_KRB5_SVC_GET_MSG)
+ krb5_free_string(ctx, (char *) msg);
+# endif
+}
+#endif /* !HAVE_KRB5_FREE_ERROR_MESSAGE */
+
+
+#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
+/*
+ * Allocate and initialize a krb5_get_init_creds_opt struct. This code
+ * assumes that an all-zero bit pattern will create a NULL pointer.
+ */
+krb5_error_code
+krb5_get_init_creds_opt_alloc(krb5_context ctx, krb5_get_init_creds_opt **opts)
+{
+ *opts = calloc(1, sizeof(krb5_get_init_creds_opt));
+ if (*opts == NULL)
+ return errno;
+ krb5_get_init_creds_opt_init(*opts);
+ return 0;
+}
+#endif /* !HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC */
+
+
+#ifndef HAVE_KRB5_PRINCIPAL_GET_REALM
+/*
+ * Return the realm of a principal as a const char *.
+ */
+const char *
+krb5_principal_get_realm(krb5_context ctx UNUSED, krb5_const_principal princ)
+{
+ const krb5_data *data;
+
+ data = krb5_princ_realm(ctx, princ);
+ if (data == NULL || data->data == NULL)
+ return NULL;
+ return data->data;
+}
+#endif /* !HAVE_KRB5_PRINCIPAL_GET_REALM */
diff --git a/portable/krb5.h b/portable/krb5.h
new file mode 100644
index 0000000..d9ef283
--- /dev/null
+++ b/portable/krb5.h
@@ -0,0 +1,83 @@
+/*
+ * Portability wrapper around krb5.h.
+ *
+ * This header includes krb5.h and then adjusts for various portability
+ * issues, primarily between MIT Kerberos and Heimdal, so that code can be
+ * written to a consistent API.
+ *
+ * Unfortunately, due to the nature of the differences between MIT Kerberos
+ * and Heimdal, it's not possible to write code to either one of the APIs and
+ * adjust for the other one. In general, this header tries to make available
+ * the Heimdal API and fix it for MIT Kerberos, but there are places where MIT
+ * Kerberos requires a more specific call. For those cases, it provides the
+ * most specific interface.
+ *
+ * For example, MIT Kerberos has krb5_free_unparsed_name() whereas Heimdal
+ * prefers the generic krb5_xfree(). In this case, this header provides
+ * krb5_free_unparsed_name() for both APIs since it's the most specific call.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * This work is hereby placed in the public domain by its author.
+ */
+
+#ifndef PORTABLE_KRB5_H
+#define PORTABLE_KRB5_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+#include <krb5.h>
+
+BEGIN_DECLS
+
+/* Default to a hidden visibility for all portability functions. */
+#pragma GCC visibility push(hidden)
+
+/*
+ * krb5_{get,free}_error_message are the preferred APIs for both current MIT
+ * and current Heimdal, but there are tons of older APIs we may have to fall
+ * back on for earlier versions.
+ *
+ * This function should be called immediately after the corresponding error
+ * without any intervening Kerberos calls. Otherwise, the correct error
+ * message and supporting information may not be returned.
+ */
+#ifndef HAVE_KRB5_GET_ERROR_MESSAGE
+const char *krb5_get_error_message(krb5_context, krb5_error_code);
+#endif
+#ifndef HAVE_KRB5_FREE_ERROR_MESSAGE
+void krb5_free_error_message(krb5_context, const char *);
+#endif
+
+/*
+ * Both current MIT and current Heimdal prefer _opt_alloc, but older versions
+ * of both require allocating your own struct and calling _opt_init.
+ */
+#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
+krb5_error_code krb5_get_init_creds_opt_alloc(krb5_context,
+ krb5_get_init_creds_opt **);
+#endif
+
+/* Heimdal-specific. */
+#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS
+#define krb5_get_init_creds_opt_set_default_flags(c, p, r, o) /* empty */
+#endif
+
+/* Heimdal: krb5_kt_free_entry, MIT: krb5_free_keytab_entry_contents. */
+#ifndef HAVE_KRB5_KT_FREE_ENTRY
+# define krb5_kt_free_entry(c, e) krb5_free_keytab_entry_contents((c), (e))
+#endif
+
+/*
+ * Heimdal provides a nice function that just returns a const char *. On MIT,
+ * there's an accessor macro that returns the krb5_data pointer, wihch
+ * requires more work to get at the underlying char *.
+ */
+#ifndef HAVE_KRB5_PRINCIPAL_GET_REALM
+const char *krb5_principal_get_realm(krb5_context, krb5_const_principal);
+#endif
+
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
+#endif /* !PORTABLE_KRB5_H */
diff --git a/portable/macros.h b/portable/macros.h
index dcffa59..8d5adbd 100644
--- a/portable/macros.h
+++ b/portable/macros.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Portability macros used in include files.
*
* Written by Russ Allbery <rra@stanford.edu>
diff --git a/portable/mkstemp.c b/portable/mkstemp.c
new file mode 100644
index 0000000..dd2a485
--- /dev/null
+++ b/portable/mkstemp.c
@@ -0,0 +1,87 @@
+/*
+ * Replacement for a missing mkstemp.
+ *
+ * Provides the same functionality as the library function mkstemp for those
+ * systems that don't have it.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * This work is hereby placed in the public domain by its author.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/time.h>
+
+/*
+ * If we're running the test suite, rename mkstemp to avoid conflicts with the
+ * system version. #undef it first because some systems may define it to
+ * another name.
+ */
+#if TESTING
+# undef mkstemp
+# define mkstemp test_mkstemp
+int test_mkstemp(char *);
+#endif
+
+/* Pick the longest available integer type. */
+#if HAVE_LONG_LONG
+typedef unsigned long long long_int_type;
+#else
+typedef unsigned long long_int_type;
+#endif
+
+int
+mkstemp(char *template)
+{
+ static const char letters[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ size_t length;
+ char *XXXXXX;
+ struct timeval tv;
+ long_int_type randnum, working;
+ int i, tries, fd;
+
+ /*
+ * Make sure we have a valid template and initialize p to point at the
+ * beginning of the template portion of the string.
+ */
+ length = strlen(template);
+ if (length < 6) {
+ errno = EINVAL;
+ return -1;
+ }
+ XXXXXX = template + length - 6;
+ if (strcmp(XXXXXX, "XXXXXX") != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Get some more-or-less random information. */
+ gettimeofday(&tv, NULL);
+ randnum = ((long_int_type) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid();
+
+ /*
+ * Now, try to find a working file name. We try no more than TMP_MAX file
+ * names.
+ */
+ for (tries = 0; tries < TMP_MAX; tries++) {
+ for (working = randnum, i = 0; i < 6; i++) {
+ XXXXXX[i] = letters[working % 62];
+ working /= 62;
+ }
+ fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if (fd >= 0 || (errno != EEXIST && errno != EISDIR))
+ return fd;
+
+ /*
+ * This is a relatively random increment. Cut off the tail end of
+ * tv_usec since it's often predictable.
+ */
+ randnum += (tv.tv_usec >> 10) & 0xfff;
+ }
+ errno = EEXIST;
+ return -1;
+}
diff --git a/portable/setenv.c b/portable/setenv.c
new file mode 100644
index 0000000..d66ddcd
--- /dev/null
+++ b/portable/setenv.c
@@ -0,0 +1,61 @@
+/*
+ * Replacement for a missing setenv.
+ *
+ * Provides the same functionality as the standard library routine setenv for
+ * those platforms that don't have it.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * This work is hereby placed in the public domain by its author.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+/*
+ * If we're running the test suite, rename setenv to avoid conflicts with
+ * the system version.
+ */
+#if TESTING
+# define setenv test_setenv
+int test_setenv(const char *, const char *, int);
+#endif
+
+int
+setenv(const char *name, const char *value, int overwrite)
+{
+ char *envstring;
+ size_t size;
+
+ if (!overwrite && getenv(name) != NULL)
+ return 0;
+
+ /*
+ * Allocate memory for the environment string. We intentionally don't use
+ * concat here, or the xmalloc family of allocation routines, since the
+ * intention is to provide a replacement for the standard library function
+ * which sets errno and returns in the event of a memory allocation
+ * failure.
+ */
+ size = strlen(name) + 1 + strlen(value) + 1;
+ envstring = malloc(size);
+ if (envstring == NULL)
+ return -1;
+
+ /*
+ * Build the environment string and add it to the environment using
+ * putenv. Systems without putenv lose, but XPG4 requires it.
+ */
+ strlcpy(envstring, name, size);
+ strlcat(envstring, "=", size);
+ strlcat(envstring, value, size);
+ return putenv(envstring);
+
+ /*
+ * Note that the memory allocated is not freed. This is intentional; many
+ * implementations of putenv assume that the string passed to putenv will
+ * never be freed and don't make a copy of it. Repeated use of this
+ * function will therefore leak memory, since most implementations of
+ * putenv also don't free strings removed from the environment (due to
+ * being overwritten).
+ */
+}
diff --git a/portable/snprintf.c b/portable/snprintf.c
index 3c39de8..ab3121c 100644
--- a/portable/snprintf.c
+++ b/portable/snprintf.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Replacement for a missing snprintf or vsnprintf.
*
* The following implementation of snprintf was taken mostly verbatim from
@@ -110,13 +109,10 @@
#define VA_SHIFT(v,t) ; /* no-op for ANSI */
#define VA_END va_end(ap)
-#ifdef HAVE_LONG_DOUBLE
+/* Assume all compilers support long double, per Autoconf documentation. */
#define LDOUBLE long double
-#else
-#define LDOUBLE double
-#endif
-#ifdef HAVE_LONG_LONG
+#ifdef HAVE_LONG_LONG_INT
# define LLONG long long
#else
# define LLONG long
diff --git a/portable/stdbool.h b/portable/stdbool.h
index 61dd8a1..bfbf4c4 100644
--- a/portable/stdbool.h
+++ b/portable/stdbool.h
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Portability wrapper around <stdbool.h>.
*
* Provides the bool and _Bool types and the true and false constants,
@@ -16,7 +15,9 @@
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
-# if !HAVE__BOOL
+# if HAVE__BOOL
+# define bool _Bool
+# else
# ifdef __cplusplus
typedef bool _Bool;
# elif _WIN32
diff --git a/portable/strlcat.c b/portable/strlcat.c
index 4816f90..f696db3 100644
--- a/portable/strlcat.c
+++ b/portable/strlcat.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Replacement for a missing strlcat.
*
* Provides the same functionality as the *BSD function strlcat, originally
diff --git a/portable/strlcpy.c b/portable/strlcpy.c
index d281645..596e968 100644
--- a/portable/strlcpy.c
+++ b/portable/strlcpy.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Replacement for a missing strlcpy.
*
* Provides the same functionality as the *BSD function strlcpy, originally
diff --git a/portable/system.h b/portable/system.h
index 1408ba7..461601b 100644
--- a/portable/system.h
+++ b/portable/system.h
@@ -1,7 +1,9 @@
-/* $Id$
+/*
+ * Standard system includes and portability adjustments.
*
* Declarations of routines and variables in the C library. Including this
- * file is the equivalent of including all of the following headers, portably:
+ * file is the equivalent of including all of the following headers,
+ * portably:
*
* #include <sys/types.h>
* #include <stdarg.h>
@@ -13,8 +15,8 @@
* #include <string.h>
* #include <unistd.h>
*
- * Missing functions are provided via #define or prototyped if available.
- * Also provides some standard #defines.
+ * Missing functions are provided via #define or prototyped if available from
+ * the portable helper library. Also provides some standard #defines.
*
* Written by Russ Allbery <rra@stanford.edu>
* This work is hereby placed in the public domain by its author.
@@ -56,13 +58,17 @@
BEGIN_DECLS
+/* Default to a hidden visibility for all portability functions. */
+#pragma GCC visibility push(hidden)
+
/*
* Provide prototypes for functions not declared in system headers. Use the
- * HAVE_DECL macros for those functions that may be prototyped but
- * implemented incorrectly or implemented without a prototype.
+ * HAVE_DECL macros for those functions that may be prototyped but implemented
+ * incorrectly or implemented without a prototype.
*/
#if !HAVE_ASPRINTF
-extern int asprintf(char **, const char *, ...);
+extern int asprintf(char **, const char *, ...)
+ __attribute__((__format__(printf, 2, 3)));
extern int vasprintf(char **, const char *, va_list);
#endif
#if !HAVE_DECL_SNPRINTF
@@ -72,6 +78,12 @@ extern int snprintf(char *, size_t, const char *, ...)
#if !HAVE_DECL_VSNPRINTF
extern int vsnprintf(char *, size_t, const char *, va_list);
#endif
+#if !HAVE_MKSTEMP
+extern int mkstemp(char *);
+#endif
+#if !HAVE_SETENV
+extern int setenv(const char *, const char *, int);
+#endif
#if !HAVE_STRLCAT
extern size_t strlcat(char *, const char *, size_t);
#endif
@@ -79,6 +91,9 @@ extern size_t strlcat(char *, const char *, size_t);
extern size_t strlcpy(char *, const char *, size_t);
#endif
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
END_DECLS
/* Windows provides snprintf under a different name. */
@@ -91,9 +106,9 @@ END_DECLS
* been defined, all the rest almost certainly have.
*/
#ifndef STDIN_FILENO
-# define STDIN_FILENO 0
-# define STDOUT_FILENO 1
-# define STDERR_FILENO 2
+# define STDIN_FILENO 0
+# define STDOUT_FILENO 1
+# define STDERR_FILENO 2
#endif
/*
@@ -102,9 +117,9 @@ END_DECLS
*/
#ifndef va_copy
# ifdef __va_copy
-# define va_copy(d, s) __va_copy((d), (s))
+# define va_copy(d, s) __va_copy((d), (s))
# else
-# define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list))
+# define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list))
# endif
#endif
diff --git a/portable/uio.h b/portable/uio.h
new file mode 100644
index 0000000..3c9e840
--- /dev/null
+++ b/portable/uio.h
@@ -0,0 +1,27 @@
+/*
+ * Portability wrapper around <sys/uio.h>.
+ *
+ * Provides a definition of the iovec struct for platforms that don't have it
+ * (primarily Windows). Currently, the corresponding readv and writev
+ * functions are not provided or prototyped here.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * This work is hereby placed in the public domain by its author.
+ */
+
+#ifndef PORTABLE_UIO_H
+#define PORTABLE_UIO_H 1
+
+#include <sys/types.h>
+
+/* remctl.h provides its own definition of this struct on Windows. */
+#if defined(HAVE_SYS_UIO_H)
+# include <sys/uio.h>
+#elif !defined(REMCTL_H)
+struct iovec {
+ void *iov_base;
+ size_t iov_len;
+};
+#endif
+
+#endif /* !PORTABLE_UIO_H */
diff --git a/server/keytab-backend b/server/keytab-backend
index 06fed3d..7b6adb4 100755
--- a/server/keytab-backend
+++ b/server/keytab-backend
@@ -1,5 +1,4 @@
#!/usr/bin/perl
-our $ID = q$Id$;
#
# keytab-backend -- Extract keytabs from the KDC without changing the key.
#
@@ -18,7 +17,8 @@ our $ID = q$Id$;
# The keytab for the extracted principal will be printed to standard output.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2006, 2007, 2008, 2010
+# Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -156,6 +156,10 @@ __END__
# Documentation
##############################################################################
+=for stopwords
+keytab-backend keytabs KDC keytab kadmin.local -norandkey ktadd remctld
+auth Allbery rekeying
+
=head1 NAME
keytab-backend - Extract keytabs from the KDC without changing the key
@@ -166,27 +170,28 @@ B<keytab-backend> retrieve I<principal>
=head1 DESCRIPTION
-B<keytab-backend> retrieves a keytab for an existing principal from the KDC
-database without changing the current key. It allows generation of a keytab
-for a service without rekeying that service. It requires a B<kadmin.local>
-patched to support the B<-norandkey> option to B<ktadd>.
+B<keytab-backend> retrieves a keytab for an existing principal from the
+KDC database without changing the current key. It allows generation of a
+keytab for a service without rekeying that service. It requires a
+B<kadmin.local> patched to support the B<-norandkey> option to B<ktadd>.
-This script is intended to run under B<remctld>. On success, it prints the
-keytab to standard output, logs a success message to syslog (facility auth,
-priority info), and exits with status 0. On failure, it prints out an error
-message, logs an error to syslog (facility auth, priority err), and exits
-with a non-zero status.
+This script is intended to run under B<remctld>. On success, it prints
+the keytab to standard output, logs a success message to syslog (facility
+auth, priority info), and exits with status 0. On failure, it prints out
+an error message, logs an error to syslog (facility auth, priority err),
+and exits with a non-zero status.
The principal is checked for basic sanity (only accepting alphanumerics,
-C<_>, and C<-> with an optional instance and then only alphanumerics, C<_>,
-C<->, and C<.> in the realm) and then checked against a configuration file
-that lists regexes of principals that can be retrieved. When deploying this
-software, limit as tightly as possible which principals can be downloaded in
-this fashion. Generally only shared service principals used on multiple
-systems should be made available in this way.
+C<_>, and C<-> with an optional instance and then only alphanumerics,
+C<_>, C<->, and C<.> in the realm) and then checked against a
+configuration file that lists regexes of principals that can be retrieved.
+When deploying this software, limit as tightly as possible which
+principals can be downloaded in this fashion. Generally only shared
+service principals used on multiple systems should be made available in
+this way.
-B<keytab-backend> does not do any authorization checks. Those should be done
-by B<remctld> before it is called.
+B<keytab-backend> does not do any authorization checks. Those should be
+done by B<remctld> before it is called.
=head1 FILES
@@ -194,19 +199,19 @@ by B<remctld> before it is called.
=item F</etc/krb5kdc/allow-extract>
-The configuration file that controls which principals can have their keytabs
-retrieved. Blank lines and lines starting with C<#>, as well as anything
-after C<#> on a line, are ignored. All other lines should be Perl regular
-expressions, one per line, that match principals whose keytabs can be
-retrieved by B<keytab-backend>. Any principal that does not match one of
-those regular expressions cannot be retrieved.
+The configuration file that controls which principals can have their
+keytabs retrieved. Blank lines and lines starting with C<#>, as well as
+anything after C<#> on a line, are ignored. All other lines should be
+Perl regular expressions, one per line, that match principals whose
+keytabs can be retrieved by B<keytab-backend>. Any principal that does
+not match one of those regular expressions cannot be retrieved.
=item F</var/lib/keytabs>
The temporary directory used for creating keytabs. B<keytab-backend> will
-create the keytab in this directory, make sure that was successful, and then
-delete the temporary file after the results have been sent to standard
-output.
+create the keytab in this directory, make sure that was successful, and
+then delete the temporary file after the results have been sent to
+standard output.
=back
@@ -214,8 +219,8 @@ output.
kadmin.local(8), remctld(8)
-This program is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This program is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/server/keytab-backend.8 b/server/keytab-backend.8
new file mode 100644
index 0000000..9dd4e76
--- /dev/null
+++ b/server/keytab-backend.8
@@ -0,0 +1,185 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "KEYTAB-BACKEND 8"
+.TH KEYTAB-BACKEND 8 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+keytab\-backend \- Extract keytabs from the KDC without changing the key
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBkeytab-backend\fR retrieve \fIprincipal\fR
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBkeytab-backend\fR retrieves a keytab for an existing principal from the
+\&\s-1KDC\s0 database without changing the current key. It allows generation of a
+keytab for a service without rekeying that service. It requires a
+\&\fBkadmin.local\fR patched to support the \fB\-norandkey\fR option to \fBktadd\fR.
+.PP
+This script is intended to run under \fBremctld\fR. On success, it prints
+the keytab to standard output, logs a success message to syslog (facility
+auth, priority info), and exits with status 0. On failure, it prints out
+an error message, logs an error to syslog (facility auth, priority err),
+and exits with a non-zero status.
+.PP
+The principal is checked for basic sanity (only accepting alphanumerics,
+\&\f(CW\*(C`_\*(C'\fR, and \f(CW\*(C`\-\*(C'\fR with an optional instance and then only alphanumerics,
+\&\f(CW\*(C`_\*(C'\fR, \f(CW\*(C`\-\*(C'\fR, and \f(CW\*(C`.\*(C'\fR in the realm) and then checked against a
+configuration file that lists regexes of principals that can be retrieved.
+When deploying this software, limit as tightly as possible which
+principals can be downloaded in this fashion. Generally only shared
+service principals used on multiple systems should be made available in
+this way.
+.PP
+\&\fBkeytab-backend\fR does not do any authorization checks. Those should be
+done by \fBremctld\fR before it is called.
+.SH "FILES"
+.IX Header "FILES"
+.IP "\fI/etc/krb5kdc/allow\-extract\fR" 4
+.IX Item "/etc/krb5kdc/allow-extract"
+The configuration file that controls which principals can have their
+keytabs retrieved. Blank lines and lines starting with \f(CW\*(C`#\*(C'\fR, as well as
+anything after \f(CW\*(C`#\*(C'\fR on a line, are ignored. All other lines should be
+Perl regular expressions, one per line, that match principals whose
+keytabs can be retrieved by \fBkeytab-backend\fR. Any principal that does
+not match one of those regular expressions cannot be retrieved.
+.IP "\fI/var/lib/keytabs\fR" 4
+.IX Item "/var/lib/keytabs"
+The temporary directory used for creating keytabs. \fBkeytab-backend\fR will
+create the keytab in this directory, make sure that was successful, and
+then delete the temporary file after the results have been sent to
+standard output.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIkadmin.local\fR\|(8), \fIremctld\fR\|(8)
+.PP
+This program is part of the wallet system. The current version is
+available from <http://www.eyrie.org/~eagle/software/wallet/>.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>
diff --git a/server/wallet-admin b/server/wallet-admin
index 4c27e9b..828cfc5 100755
--- a/server/wallet-admin
+++ b/server/wallet-admin
@@ -1,10 +1,9 @@
#!/usr/bin/perl -w
-our $ID = q$Id$;
#
-# wallet-admin -- Wallet server administrative commands.
+# wallet-backend -- Wallet server administrative commands.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -43,11 +42,11 @@ sub command {
unless $args[0] =~ /^[^\@\s]+\@\S+$/;
$admin->initialize (@args) or die $admin->error, "\n";
} elsif ($command eq 'list') {
- die "too many arguments to list\n" if @args > 1;
+ die "too many arguments to list\n" if @args > 4;
die "too few arguments to list\n" if @args < 1;
- my ($type) = @args;
+ my ($type, $subtype, @search) = @args;
if ($type eq 'objects') {
- my @objects = $admin->list_objects;
+ my @objects = $admin->list_objects ($subtype, @search);
if (!@objects and $admin->error) {
die $admin->error, "\n";
}
@@ -55,7 +54,7 @@ sub command {
print join (' ', @$object), "\n";
}
} elsif ($type eq 'acls') {
- my @acls = $admin->list_acls;
+ my @acls = $admin->list_acls ($subtype, @search);
if (!@acls and $admin->error) {
die $admin->error, "\n";
}
@@ -65,6 +64,22 @@ sub command {
} else {
die "only objects or acls are supported for list\n";
}
+ } elsif ($command eq 'report') {
+ die "too few arguments to report\n" if @args < 1;
+ my $report = shift @args;
+ if ($report eq 'owners') {
+ die "too many arguments to report owners\n" if @args > 2;
+ die "too few arguments to report owners\n" if @args < 2;
+ my @lines = $admin->report_owners (@args);
+ if (!@lines and $admin->error) {
+ die $admin->error, "\n";
+ }
+ for my $line (@lines) {
+ print join (' ', @$line), "\n";
+ }
+ } else {
+ die "unknown report type $report\n";
+ }
} elsif ($command eq 'register') {
die "too many arguments to register\n" if @args > 3;
die "too few arguments to register\n" if @args < 3;
@@ -95,6 +110,9 @@ __END__
wallet-admin - Wallet server administrative commands
+=for stopwords
+metadata ACL hostname backend acl acls wildcard SQL Allbery
+
=head1 SYNOPSIS
B<wallet-admin> I<command> [I<args> ...]
@@ -141,10 +159,10 @@ Before running C<initialize>, the wallet system has to be configured. See
Wallet::Config(3) for more details. Depending on the database backend
used, the database may also have to be created in advance.
-=item list (acls | objects)
+=item list (acls | objects) [ <searchtype> [ <arg> ... ] ]
-Returns a list of all ACLs or objects in the database. ACLs will be
-listed in the form:
+Returns a list of ACLs or objects in the database. ACLs will be listed
+in the form:
<name> (ACL ID: <id>)
@@ -156,6 +174,51 @@ be listed in the form:
In both cases, there will be one line per ACL or object.
+If no search type is given, all the ACLs or objects in the database will
+be returned. If a search type (and possible search arguments) are given,
+then the ACLs or objects will be limited to those that match the search.
+
+The currently supported object search types are:
+
+=over 4
+
+=item list objects type <type>
+
+Returns all objects of the given type.
+
+=item list objects flag <flag>
+
+Returns all objects which have the given flag set.
+
+=item list objects owner <acl name>
+
+Returns all objects owned by the given ACL name.
+
+=item list objects acl <acl name>
+
+Returns all objects for which the given ACL name has any permissions.
+This includes those objects owned by the ACL, but also those for which the
+ACL has get permissions, for example.
+
+=back
+
+The currently supported ACL search types are:
+
+=over 4
+
+=item list acls empty
+
+Returns all ACLs which have no entries, generally so that abandoned ACLs
+can be destroyed.
+
+=item list acls entry <schema> <identifier>
+
+Returns all ACLs containing an entry with given schema and identifier.
+The schema is used for an exact search, while the identifier given will
+match any identifier containing that text, for flexibility.
+
+=back
+
=item register (object | verifier) <type> <class>
Registers an implementation of a wallet object or ACL verifier in the
@@ -169,14 +232,35 @@ default as part of database initialization, so this command is used
primarily to register local implementations of additional object types or
ACL schemes.
+=item report <type> [ <arg> ... ]
+
+Runs a wallet report. The currently supported report types are:
+
+=over 4
+
+=item report owners <type-pattern> <name-pattern>
+
+Returns a list of all ACL lines in owner ACLs for all objects matching
+both <type-pattern> and <name-pattern>. These can be the type or name of
+objects or they can be patterns using C<%> as the wildcard character
+following the normal rules of SQL patterns.
+
+The output will be one line per ACL line in the form:
+
+ <scheme> <identifier>
+
+with duplicates suppressed.
+
+=back
+
=back
=head1 SEE ALSO
Wallet::Admin(3), Wallet::Config(3), wallet-backend(8)
-This program is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This program is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/server/wallet-admin.8 b/server/wallet-admin.8
new file mode 100644
index 0000000..4d262dc
--- /dev/null
+++ b/server/wallet-admin.8
@@ -0,0 +1,269 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "WALLET-ADMIN 8"
+.TH WALLET-ADMIN 8 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+wallet\-admin \- Wallet server administrative commands
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBwallet-admin\fR \fIcommand\fR [\fIargs\fR ...]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBwallet-admin\fR provides a command-line interface for performing
+administrative actions for the wallet system, such as setting up a new
+database or running reports. It is intended to be run on the wallet
+server as a user with access to the wallet database and configuration.
+.PP
+This program is a fairly thin wrapper around Wallet::Admin that translates
+command strings into method calls and returns the results.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fBwallet-admin\fR takes no traditional options.
+.SH "COMMANDS"
+.IX Header "COMMANDS"
+.IP "destroy" 4
+.IX Item "destroy"
+Deletes all data in the wallet database and drops all of the
+wallet-created tables, restoring the database to its state prior to an
+\&\f(CW\*(C`initialize\*(C'\fR command. Since this command is destructive and cannot be
+easily recovered from, \fBwallet-admin\fR will prompt first to be sure the
+user intends to do this.
+.IP "initialize <principal>" 4
+.IX Item "initialize <principal>"
+Given an empty database, initializes it for use with the wallet server by
+creating the necessary tables and initial metadata. Also creates an \s-1ACL\s0
+with the name \s-1ADMIN\s0, used for administrative privileges to the wallet
+system, and adds an \s-1ACL\s0 entry to it with a scheme of \f(CW\*(C`krb5\*(C'\fR and an
+instance of <principal>. This bootstraps the authentication system and
+allows that user to make further changes to the \s-1ADMIN\s0 \s-1ACL\s0 and the rest of
+the wallet database. \f(CW\*(C`initialize\*(C'\fR uses \f(CW\*(C`localhost\*(C'\fR as the hostname and
+<principal> as the user when logging the history of the \s-1ADMIN\s0 \s-1ACL\s0 creation
+and for any subsequent actions required to initialize the database.
+.Sp
+Before running \f(CW\*(C`initialize\*(C'\fR, the wallet system has to be configured. See
+\&\fIWallet::Config\fR\|(3) for more details. Depending on the database backend
+used, the database may also have to be created in advance.
+.IP "list (acls | objects) [ <searchtype> [ <arg> ... ] ]" 4
+.IX Item "list (acls | objects) [ <searchtype> [ <arg> ... ] ]"
+Returns a list of ACLs or objects in the database. ACLs will be listed
+in the form:
+.Sp
+.Vb 1
+\& <name> (ACL ID: <id>)
+.Ve
+.Sp
+where <name> is the human-readable name and <id> is the numeric \s-1ID\s0. The
+numeric \s-1ID\s0 is what's used internally by the wallet system. Objects will
+be listed in the form:
+.Sp
+.Vb 1
+\& <type> <name>
+.Ve
+.Sp
+In both cases, there will be one line per \s-1ACL\s0 or object.
+.Sp
+If no search type is given, all the ACLs or objects in the database will
+be returned. If a search type (and possible search arguments) are given,
+then the ACLs or objects will be limited to those that match the search.
+.Sp
+The currently supported object search types are:
+.RS 4
+.IP "list objects type <type>" 4
+.IX Item "list objects type <type>"
+Returns all objects of the given type.
+.IP "list objects flag <flag>" 4
+.IX Item "list objects flag <flag>"
+Returns all objects which have the given flag set.
+.IP "list objects owner <acl name>" 4
+.IX Item "list objects owner <acl name>"
+Returns all objects owned by the given \s-1ACL\s0 name.
+.IP "list objects acl <acl name>" 4
+.IX Item "list objects acl <acl name>"
+Returns all objects for which the given \s-1ACL\s0 name has any permissions.
+This includes those objects owned by the \s-1ACL\s0, but also those for which the
+\&\s-1ACL\s0 has get permissions, for example.
+.RE
+.RS 4
+.Sp
+The currently supported \s-1ACL\s0 search types are:
+.IP "list acls empty" 4
+.IX Item "list acls empty"
+Returns all ACLs which have no entries, generally so that abandoned ACLs
+can be destroyed.
+.IP "list acls entry <schema> <identifier>" 4
+.IX Item "list acls entry <schema> <identifier>"
+Returns all ACLs containing an entry with given schema and identifier.
+The schema is used for an exact search, while the identifier given will
+match any identifier containing that text, for flexibility.
+.RE
+.RS 4
+.RE
+.IP "register (object | verifier) <type> <class>" 4
+.IX Item "register (object | verifier) <type> <class>"
+Registers an implementation of a wallet object or \s-1ACL\s0 verifier in the
+wallet database. The Perl class <class> is registered as the
+implementation of an object of type <type> or an \s-1ACL\s0 verifier of scheme
+<type>, allowing creation of objects with that type or \s-1ACL\s0 lines with that
+scheme.
+.Sp
+All object and \s-1ACL\s0 implementations that come with wallet are registered by
+default as part of database initialization, so this command is used
+primarily to register local implementations of additional object types or
+\&\s-1ACL\s0 schemes.
+.IP "report <type> [ <arg> ... ]" 4
+.IX Item "report <type> [ <arg> ... ]"
+Runs a wallet report. The currently supported report types are:
+.RS 4
+.IP "report owners <type\-pattern> <name\-pattern>" 4
+.IX Item "report owners <type-pattern> <name-pattern>"
+Returns a list of all \s-1ACL\s0 lines in owner ACLs for all objects matching
+both <type\-pattern> and <name\-pattern>. These can be the type or name of
+objects or they can be patterns using \f(CW\*(C`%\*(C'\fR as the wildcard character
+following the normal rules of \s-1SQL\s0 patterns.
+.Sp
+The output will be one line per \s-1ACL\s0 line in the form:
+.Sp
+.Vb 1
+\& <scheme> <identifier>
+.Ve
+.Sp
+with duplicates suppressed.
+.RE
+.RS 4
+.RE
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIWallet::Admin\fR\|(3), \fIWallet::Config\fR\|(3), \fIwallet\-backend\fR\|(8)
+.PP
+This program is part of the wallet system. The current version is
+available from <http://www.eyrie.org/~eagle/software/wallet/>.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>
diff --git a/server/wallet-backend b/server/wallet-backend
index 74e0eb0..0a611db 100755
--- a/server/wallet-backend
+++ b/server/wallet-backend
@@ -1,10 +1,9 @@
#!/usr/bin/perl
-our $ID = q$Id$;
#
# wallet-backend -- Wallet server for storing and retrieving secure data.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -285,7 +284,11 @@ sub command {
failure ($server->error, @_);
}
} elsif ($command eq 'store') {
- check_args (3, 3, [3], @args);
+ check_args (2, 3, [3], @args);
+ if (@args == 2) {
+ local $/;
+ $args[2] = <STDIN>;
+ }
splice (@_, 3);
$server->store (@args) or failure ($server->error, @_);
} else {
@@ -312,6 +315,11 @@ __END__
# The commands section of this document is duplicated from the documentation
# for wallet and should be kept in sync.
+=for stopwords
+wallet-backend backend backend-specific remctld ACL acl timestamp getacl
+setacl metadata keytab keytabs enctypes enctype ktadd KDC Allbery
+autocreate
+
=head1 NAME
wallet-backend - Wallet server for storing and retrieving secure data
@@ -322,20 +330,22 @@ B<wallet-backend> [B<-q>] I<command> [I<args> ...]
=head1 DESCRIPTION
-B<wallet-backend> implements the interface between B<remctld> and the wallet
-system. It is written to run under B<remctld> and expects the authenticated
-identity of the remote user in the REMOTE_USER environment variable. It
-uses REMOTE_HOST or REMOTE_ADDR if REMOTE_HOST isn't set for additional
-trace information. It accepts the command from B<remctld> on the command
-line, creates a Wallet::Server object, and calls the appropriate methods.
-
-This program is a fairly thin wrapper around Wallet::Server that translates
-command strings into method calls and returns the results. It does check
-all arguments except for the <data> argument to the store command and
-rejects any argument not matching C<^[\w_/.-]+\z>; in other words, only
-alphanumerics, underscore (C<_>), slash (C</>), period (C<.>), and hyphen
-(C<->) are permitted in arguments. This provides some additional security
-over and above the checking already done by the rest of the wallet code.
+B<wallet-backend> implements the interface between B<remctld> and the
+wallet system. It is written to run under B<remctld> and expects the
+authenticated identity of the remote user in the REMOTE_USER environment
+variable. It uses REMOTE_HOST or REMOTE_ADDR if REMOTE_HOST isn't set for
+additional trace information. It accepts the command from B<remctld> on
+the command line, creates a Wallet::Server object, and calls the
+appropriate methods.
+
+This program is a fairly thin wrapper around Wallet::Server that
+translates command strings into method calls and returns the results. It
+does check all arguments except for the <data> argument to the store
+command and rejects any argument not matching C<^[\w_/.-]+\z>; in other
+words, only alphanumerics, underscore (C<_>), slash (C</>), period (C<.>),
+and hyphen (C<->) are permitted in arguments. This provides some
+additional security over and above the checking already done by the rest
+of the wallet code.
=head1 OPTIONS
@@ -401,7 +411,7 @@ Display the history of the ACL <id>. Each change to the ACL (not
including changes to the name of the ACL) will be represented by two
lines. The first line will have a timestamp of the change followed by a
description of the change, and the second line will give the user who made
-the change and the host from which the change was mde.
+the change and the host from which the change was made.
=item acl remove <id> <scheme> <identifier>
@@ -448,8 +458,8 @@ The expiration will be displayed in seconds since epoch.
If <date> is given, sets the expiration on the object identified by <type>
and <name> to <date> and (if given) <time>. <date> must be in the format
-C<YYYY-MM-DD> and <time> in the format C<HH:MM:SS>. If <date> is the empty
-string, clears the expiration of the object.
+C<YYYY-MM-DD> and <time> in the format C<HH:MM:SS>. If <date> is the
+empty string, clears the expiration of the object.
Currently, the expiration of an object is not used.
@@ -461,16 +471,16 @@ Clears the flag <flag> on the object identified by <type> and <name>.
Sets the flag <flag> on the object identified by <type> and <name>.
Recognized flags are C<locked>, which prevents all further actions on that
-object until the flag is cleared, and C<unchanging>, which tells the object
-backend to not generate new data on get but instead return the same data as
-previously returned. The C<unchanging> flag is not meaningful for objects
-that do not generate new data on the fly.
+object until the flag is cleared, and C<unchanging>, which tells the
+object backend to not generate new data on get but instead return the same
+data as previously returned. The C<unchanging> flag is not meaningful for
+objects that do not generate new data on the fly.
=item get <type> <name>
-Prints to standard output the data associated with the object identified by
-<type> and <name>. This may trigger generation of new data and invalidate
-old data for that object depending on the object type.
+Prints to standard output the data associated with the object identified
+by <type> and <name>. This may trigger generation of new data and
+invalidate old data for that object depending on the object type.
=item getacl <type> <name> <acl>
@@ -486,17 +496,17 @@ or setting it.
Prints the object attribute <attr> for the object identified by <type> and
<name>. Attributes are used to store backend-specific information for a
particular object type, and <attr> must be an attribute type known to the
-underlying object implementation. The attribute values, if any, are printed
-one per line. If the attribute is not set on this object, nothing is
-printed.
+underlying object implementation. The attribute values, if any, are
+printed one per line. If the attribute is not set on this object, nothing
+is printed.
=item history <type> <name>
-Displays the history for the object identified by <type> and <name>.
-This human-readable output will have two lines for each action that
-changes the object, plus for any get action. The first line has the
-timestamp of the action and the action, and the second line gives the user
-who performed the action and the host from which they performed it.
+Displays the history for the object identified by <type> and <name>. This
+human-readable output will have two lines for each action that changes the
+object, plus for any get action. The first line has the timestamp of the
+action and the action, and the second line gives the user who performed
+the action and the host from which they performed it.
=item owner <type> <name> [<owner>]
@@ -530,15 +540,11 @@ name, the owner, any specific ACLs set on the object, the expiration if
any, and the user, remote host, and time when the object was created, last
stored, and last downloaded.
-=item store <type> <name> <data>
+=item store <type> <name> [<data>]
Stores <data> for the object identified by <type> and <name> for later
-retrieval with C<get>. Not all object types support this.
-
-Currently, <data> is limited to not containing nul characters and may
-therefore not be binary data, and is limited by the maximum command line
-length of the operating system of the wallet server. These restrictions
-will be lifted in the future.
+retrieval with C<get>. Not all object types support this. If <data> is
+not given as an argument, it will be read from standard input.
=back
@@ -559,47 +565,27 @@ Keytab objects support the following attributes:
Restricts the generated keytab to a specific set of encryption types. The
values of this attribute must be enctype strings recognized by Kerberos
-(strings like C<aes256-cts> or C<des-cbc-crc>). Note that the salt should
-not be included; since the salt is irrelevant for keytab keys, it will
-always be set to C<normal> by the wallet.
+(strings like C<aes256-cts-hmac-sha1-96> or C<des-cbc-crc>). Note that
+the salt should not be included; since the salt is irrelevant for keytab
+keys, it will always be set to C<normal> by the wallet.
-If this attribute is set, the specified enctype list will be passed to ktadd
-when get() is called for that keytab. If it is not set, the default set in
-the KDC will be used.
+If this attribute is set, the specified enctype list will be passed to
+ktadd when get() is called for that keytab. If it is not set, the default
+set in the KDC will be used.
This attribute is ignored if the C<unchanging> flag is set on a keytab.
Keytabs retrieved with C<unchanging> set will contain all keys present in
the KDC for that Kerberos principal and therefore may contain different
enctypes than those requested by this attribute.
-=item sync
-
-Sets the external systems to which the key of a given principal is
-synchronized. The only supported value for this attribute is C<kaserver>,
-which says to synchronize the key with an AFS Kerberos v4 kaserver.
-
-If this attribute is set on a keytab, whenever the C<get> command is run for
-that keytab, the DES key will be extracted from that keytab and set in the
-configured AFS kaserver. The Kerberos v4 principal name will be the same as
-the Kerberos v5 principal name except that the components are separated by
-C<.> instead of C</>; the second component is truncated after the first C<.>
-if the first component is one of C<host>, C<ident>, C<imap>, C<pop>, or
-C<smtp>; and the first component is C<rcmd> if the Kerberos v5 principal
-component is C<host>. The principal name must not contain more than two
-components.
-
-If this attribute is set, calling C<destroy> will also destroy the
-principal from the AFS kaserver, with a principal mapping determined as
-above.
-
=back
=head1 SEE ALSO
Wallet::Server(3), remctld(8)
-This program is part of the wallet system. The current version is available
-from L<http://www.eyrie.org/~eagle/software/wallet/>.
+This program is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
=head1 AUTHOR
diff --git a/server/wallet-backend.8 b/server/wallet-backend.8
new file mode 100644
index 0000000..4369ba4
--- /dev/null
+++ b/server/wallet-backend.8
@@ -0,0 +1,357 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "WALLET-BACKEND 8"
+.TH WALLET-BACKEND 8 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+wallet\-backend \- Wallet server for storing and retrieving secure data
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBwallet-backend\fR [\fB\-q\fR] \fIcommand\fR [\fIargs\fR ...]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBwallet-backend\fR implements the interface between \fBremctld\fR and the
+wallet system. It is written to run under \fBremctld\fR and expects the
+authenticated identity of the remote user in the \s-1REMOTE_USER\s0 environment
+variable. It uses \s-1REMOTE_HOST\s0 or \s-1REMOTE_ADDR\s0 if \s-1REMOTE_HOST\s0 isn't set for
+additional trace information. It accepts the command from \fBremctld\fR on
+the command line, creates a Wallet::Server object, and calls the
+appropriate methods.
+.PP
+This program is a fairly thin wrapper around Wallet::Server that
+translates command strings into method calls and returns the results. It
+does check all arguments except for the <data> argument to the store
+command and rejects any argument not matching \f(CW\*(C`^[\ew_/.\-]+\ez\*(C'\fR; in other
+words, only alphanumerics, underscore (\f(CW\*(C`_\*(C'\fR), slash (\f(CW\*(C`/\*(C'\fR), period (\f(CW\*(C`.\*(C'\fR),
+and hyphen (\f(CW\*(C`\-\*(C'\fR) are permitted in arguments. This provides some
+additional security over and above the checking already done by the rest
+of the wallet code.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fB\-\-quiet\fR, \fB\-q\fR" 4
+.IX Item "--quiet, -q"
+If this option is given, \fBwallet-backend\fR will not log its actions to
+syslog.
+.SH "COMMANDS"
+.IX Header "COMMANDS"
+Most commands are only available to wallet administrators (users on the
+\&\f(CW\*(C`ADMIN\*(C'\fR \s-1ACL\s0). The exceptions are \f(CW\*(C`autocreate\*(C'\fR, \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR,
+\&\f(CW\*(C`show\*(C'\fR, \f(CW\*(C`destroy\*(C'\fR, \f(CW\*(C`flag clear\*(C'\fR, \f(CW\*(C`flag set\*(C'\fR, \f(CW\*(C`getattr\*(C'\fR, \f(CW\*(C`setattr\*(C'\fR,
+and \f(CW\*(C`history\*(C'\fR. All of those commands have their own ACLs except
+\&\f(CW\*(C`getattr\*(C'\fR and \f(CW\*(C`history\*(C'\fR, which use the \f(CW\*(C`show\*(C'\fR \s-1ACL\s0, and \f(CW\*(C`setattr\*(C'\fR,
+which uses the \f(CW\*(C`store\*(C'\fR \s-1ACL\s0. If the appropriate \s-1ACL\s0 is set, it alone is
+checked to see if the user has access. Otherwise, \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR,
+\&\f(CW\*(C`show\*(C'\fR, \f(CW\*(C`getattr\*(C'\fR, \f(CW\*(C`setattr\*(C'\fR, and \f(CW\*(C`history\*(C'\fR access is permitted if the
+user is authorized by the owner \s-1ACL\s0 of the object. \f(CW\*(C`autocreate\*(C'\fR is
+permitted if the user is listed in the default \s-1ACL\s0 for an object for that
+name.
+.PP
+Administrators can run any command on any object or \s-1ACL\s0 except for \f(CW\*(C`get\*(C'\fR
+and \f(CW\*(C`store\*(C'\fR. For \f(CW\*(C`get\*(C'\fR and \f(CW\*(C`store\*(C'\fR, they must still be authorized by
+either the appropriate specific \s-1ACL\s0 or the owner \s-1ACL\s0.
+.PP
+If the locked flag is set on an object, no commands can be run on that
+object that change data except the \f(CW\*(C`flags\*(C'\fR commands, nor can the \f(CW\*(C`get\*(C'\fR
+command be used on that object. \f(CW\*(C`show\*(C'\fR, \f(CW\*(C`history\*(C'\fR, \f(CW\*(C`getacl\*(C'\fR,
+\&\f(CW\*(C`getattr\*(C'\fR, and \f(CW\*(C`owner\*(C'\fR or \f(CW\*(C`expires\*(C'\fR without an argument can still be
+used on that object.
+.PP
+For more information on attributes, see \s-1ATTRIBUTES\s0.
+.IP "acl add <id> <scheme> <identifier>" 4
+.IX Item "acl add <id> <scheme> <identifier>"
+Adds an entry with <scheme> and <identifier> to the \s-1ACL\s0 <id>. <id> may be
+either the name of an \s-1ACL\s0 or its numeric identifier.
+.IP "acl create <name>" 4
+.IX Item "acl create <name>"
+Create a new, empty \s-1ACL\s0 with name <name>. When setting an \s-1ACL\s0 on an
+object with a set of entries that don't match an existing \s-1ACL\s0, first
+create a new \s-1ACL\s0 with \f(CW\*(C`acl create\*(C'\fR, add the appropriate entries to it
+with \f(CW\*(C`acl add\*(C'\fR, and then set the \s-1ACL\s0 on an object with the \f(CW\*(C`owner\*(C'\fR or
+\&\f(CW\*(C`setacl\*(C'\fR commands.
+.IP "acl destroy <id>" 4
+.IX Item "acl destroy <id>"
+Destroy the \s-1ACL\s0 <id>. This \s-1ACL\s0 must no longer be referenced by any object
+or the \s-1ACL\s0 destruction will fail. The special \s-1ACL\s0 named \f(CW\*(C`ADMIN\*(C'\fR cannot
+be destroyed.
+.IP "acl history <id>" 4
+.IX Item "acl history <id>"
+Display the history of the \s-1ACL\s0 <id>. Each change to the \s-1ACL\s0 (not
+including changes to the name of the \s-1ACL\s0) will be represented by two
+lines. The first line will have a timestamp of the change followed by a
+description of the change, and the second line will give the user who made
+the change and the host from which the change was made.
+.IP "acl remove <id> <scheme> <identifier>" 4
+.IX Item "acl remove <id> <scheme> <identifier>"
+Remove the entry with <scheme> and <identifier> from the \s-1ACL\s0 <id>. <id>
+may be either the name of an \s-1ACL\s0 or its numeric identifier. The last
+entry in the special \s-1ACL\s0 \f(CW\*(C`ADMIN\*(C'\fR cannot be removed to protect against
+accidental lockout, but administrators can remove themselves from the
+\&\f(CW\*(C`ADMIN\*(C'\fR \s-1ACL\s0 and can leave only a non-functioning entry on the \s-1ACL\s0. Use
+caution when removing entries from the \f(CW\*(C`ADMIN\*(C'\fR \s-1ACL\s0.
+.IP "acl show <id>" 4
+.IX Item "acl show <id>"
+Display the name, numeric \s-1ID\s0, and entries of the \s-1ACL\s0 <id>.
+.IP "autocreate <type> <name>" 4
+.IX Item "autocreate <type> <name>"
+Create a new object of type <type> with name <name>. The user must be
+listed in the default \s-1ACL\s0 for an object with that type and name, and the
+object will be created with that default \s-1ACL\s0 set as the object owner.
+.IP "check <type> <name>" 4
+.IX Item "check <type> <name>"
+Check whether an object of type <type> and name <name> already exists. If
+it does, prints \f(CW\*(C`yes\*(C'\fR; if not, prints \f(CW\*(C`no\*(C'\fR.
+.IP "create <type> <name>" 4
+.IX Item "create <type> <name>"
+Create a new object of type <type> with name <name>. With some backends,
+this will trigger creation of an entry in an external system as well.
+The new object will have no ACLs and no owner set, so usually the
+administrator will want to then set an owner with \f(CW\*(C`owner\*(C'\fR so that the
+object will be usable.
+.IP "destroy <type> <name>" 4
+.IX Item "destroy <type> <name>"
+Destroy the object identified by <type> and <name>. With some backends,
+this will trigger destruction of an object in an external system as well.
+.IP "expires <type> <name> [<date> [<time>]]" 4
+.IX Item "expires <type> <name> [<date> [<time>]]"
+If <date> is not given, displays the current expiration of the object
+identified by <type> and <name>, or \f(CW\*(C`No expiration set\*(C'\fR if none is set.
+The expiration will be displayed in seconds since epoch.
+.Sp
+If <date> is given, sets the expiration on the object identified by <type>
+and <name> to <date> and (if given) <time>. <date> must be in the format
+\&\f(CW\*(C`YYYY\-MM\-DD\*(C'\fR and <time> in the format \f(CW\*(C`HH:MM:SS\*(C'\fR. If <date> is the
+empty string, clears the expiration of the object.
+.Sp
+Currently, the expiration of an object is not used.
+.IP "flag clear <type> <name> <flag>" 4
+.IX Item "flag clear <type> <name> <flag>"
+Clears the flag <flag> on the object identified by <type> and <name>.
+.IP "flag set <type> <name> <flag>" 4
+.IX Item "flag set <type> <name> <flag>"
+Sets the flag <flag> on the object identified by <type> and <name>.
+Recognized flags are \f(CW\*(C`locked\*(C'\fR, which prevents all further actions on that
+object until the flag is cleared, and \f(CW\*(C`unchanging\*(C'\fR, which tells the
+object backend to not generate new data on get but instead return the same
+data as previously returned. The \f(CW\*(C`unchanging\*(C'\fR flag is not meaningful for
+objects that do not generate new data on the fly.
+.IP "get <type> <name>" 4
+.IX Item "get <type> <name>"
+Prints to standard output the data associated with the object identified
+by <type> and <name>. This may trigger generation of new data and
+invalidate old data for that object depending on the object type.
+.IP "getacl <type> <name> <acl>" 4
+.IX Item "getacl <type> <name> <acl>"
+Prints the \s-1ACL\s0 <acl>, which must be one of \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, \f(CW\*(C`show\*(C'\fR,
+\&\f(CW\*(C`destroy\*(C'\fR, or \f(CW\*(C`flags\*(C'\fR, for the object identified by <type> and <name>.
+Prints \f(CW\*(C`No ACL set\*(C'\fR if that \s-1ACL\s0 isn't set on that object. Remember that
+if the \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, or \f(CW\*(C`show\*(C'\fR ACLs aren't set, authorization falls
+back to checking the owner \s-1ACL\s0. See the \f(CW\*(C`owner\*(C'\fR command for displaying
+or setting it.
+.IP "getattr <type> <name> <attr>" 4
+.IX Item "getattr <type> <name> <attr>"
+Prints the object attribute <attr> for the object identified by <type> and
+<name>. Attributes are used to store backend-specific information for a
+particular object type, and <attr> must be an attribute type known to the
+underlying object implementation. The attribute values, if any, are
+printed one per line. If the attribute is not set on this object, nothing
+is printed.
+.IP "history <type> <name>" 4
+.IX Item "history <type> <name>"
+Displays the history for the object identified by <type> and <name>. This
+human-readable output will have two lines for each action that changes the
+object, plus for any get action. The first line has the timestamp of the
+action and the action, and the second line gives the user who performed
+the action and the host from which they performed it.
+.IP "owner <type> <name> [<owner>]" 4
+.IX Item "owner <type> <name> [<owner>]"
+If <owner> is not given, displays the current owner \s-1ACL\s0 of the object
+identified by <type> and <name>, or \f(CW\*(C`No owner set\*(C'\fR if none is set. The
+result will be the name of an \s-1ACL\s0.
+.Sp
+If <owner> is given, sets the owner of the object identified by <type> and
+<name> to <owner>. If <owner> is the empty string, clears the owner of
+the object.
+.IP "setacl <type> <name> <acl> <id>" 4
+.IX Item "setacl <type> <name> <acl> <id>"
+Sets the \s-1ACL\s0 <acl>, which must be one of \f(CW\*(C`get\*(C'\fR, \f(CW\*(C`store\*(C'\fR, \f(CW\*(C`show\*(C'\fR,
+\&\f(CW\*(C`destroy\*(C'\fR, or \f(CW\*(C`flags\*(C'\fR, to <id> on the object identified by <type> and
+<name>. If <id> is the empty string, clears that \s-1ACL\s0 on the object.
+.IP "setattr <type> <name> <attr> <value> [<value> ...]" 4
+.IX Item "setattr <type> <name> <attr> <value> [<value> ...]"
+Sets the object attribute <attr> for the object identified by <type> and
+<name>. Attributes are used to store backend-specific information for a
+particular object type, and <attr> must be an attribute type known to the
+underlying object implementation. To clear the attribute for this object,
+pass in a <value> of the empty string (\f(CW\*(Aq\*(Aq\fR).
+.IP "show <type> <name>" 4
+.IX Item "show <type> <name>"
+Displays the current object metadata for the object identified by <type>
+and <name>. This human-readable output will show the object type and
+name, the owner, any specific ACLs set on the object, the expiration if
+any, and the user, remote host, and time when the object was created, last
+stored, and last downloaded.
+.IP "store <type> <name> [<data>]" 4
+.IX Item "store <type> <name> [<data>]"
+Stores <data> for the object identified by <type> and <name> for later
+retrieval with \f(CW\*(C`get\*(C'\fR. Not all object types support this. If <data> is
+not given as an argument, it will be read from standard input.
+.SH "ATTRIBUTES"
+.IX Header "ATTRIBUTES"
+Object attributes store additional properties and configuration
+information for objects stored in the wallet. They are displayed as part
+of the object data with \f(CW\*(C`show\*(C'\fR, retrieved with \f(CW\*(C`getattr\*(C'\fR, and set with
+\&\f(CW\*(C`setattr\*(C'\fR.
+.SS "Keytab Attributes"
+.IX Subsection "Keytab Attributes"
+Keytab objects support the following attributes:
+.IP "enctypes" 4
+.IX Item "enctypes"
+Restricts the generated keytab to a specific set of encryption types. The
+values of this attribute must be enctype strings recognized by Kerberos
+(strings like \f(CW\*(C`aes256\-cts\-hmac\-sha1\-96\*(C'\fR or \f(CW\*(C`des\-cbc\-crc\*(C'\fR). Note that
+the salt should not be included; since the salt is irrelevant for keytab
+keys, it will always be set to \f(CW\*(C`normal\*(C'\fR by the wallet.
+.Sp
+If this attribute is set, the specified enctype list will be passed to
+ktadd when \fIget()\fR is called for that keytab. If it is not set, the default
+set in the \s-1KDC\s0 will be used.
+.Sp
+This attribute is ignored if the \f(CW\*(C`unchanging\*(C'\fR flag is set on a keytab.
+Keytabs retrieved with \f(CW\*(C`unchanging\*(C'\fR set will contain all keys present in
+the \s-1KDC\s0 for that Kerberos principal and therefore may contain different
+enctypes than those requested by this attribute.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIWallet::Server\fR\|(3), \fIremctld\fR\|(8)
+.PP
+This program is part of the wallet system. The current version is
+available from <http://www.eyrie.org/~eagle/software/wallet/>.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>
diff --git a/server/wallet-report b/server/wallet-report
new file mode 100755
index 0000000..a6b3b8d
--- /dev/null
+++ b/server/wallet-report
@@ -0,0 +1,203 @@
+#!/usr/bin/perl -w
+#
+# wallet-report -- Wallet server reporting interface.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+##############################################################################
+# Declarations and site configuration
+##############################################################################
+
+use strict;
+use Wallet::Report;
+
+##############################################################################
+# Implementation
+##############################################################################
+
+# Parse and execute a command. We wrap this in a subroutine call for easier
+# testing.
+sub command {
+ die "Usage: wallet-report <command> [<args> ...]\n" unless @_;
+ my $report = Wallet::Report->new;
+
+ # Parse command-line options and dispatch to the appropriate calls.
+ my ($command, @args) = @_;
+ if ($command eq 'acls') {
+ die "too many arguments to acls\n" if @args > 3;
+ my @acls = $report->acls (@args);
+ if (!@acls and $report->error) {
+ die $report->error, "\n";
+ }
+ for my $acl (sort { $$a[1] cmp $$b[1] } @acls) {
+ print "$$acl[1] (ACL ID: $$acl[0])\n";
+ }
+ } elsif ($command eq 'objects') {
+ die "too many arguments to objects\n" if @args > 2;
+ my @objects = $report->objects (@args);
+ if (!@objects and $report->error) {
+ die $report->error, "\n";
+ }
+ for my $object (@objects) {
+ print join (' ', @$object), "\n";
+ }
+ } elsif ($command eq 'owners') {
+ die "too many arguments to owners\n" if @args > 2;
+ die "too few arguments to owners\n" if @args < 2;
+ my @entries = $report->owners (@args);
+ if (!@entries and $report->error) {
+ die $report->error, "\n";
+ }
+ for my $entry (@entries) {
+ print join (' ', @$entry), "\n";
+ }
+ } else {
+ die "unknown command $command\n";
+ }
+}
+command (@ARGV);
+__END__
+
+##############################################################################
+# Documentation
+##############################################################################
+
+=head1 NAME
+
+wallet-report - Wallet server reporting interface
+
+=for stopwords
+metadata ACL hostname backend acl acls wildcard SQL Allbery remctl
+
+=head1 SYNOPSIS
+
+B<wallet-report> I<type> [I<args> ...]
+
+=head1 DESCRIPTION
+
+B<wallet-report> provides a command-line interface for running reports on
+the wallet database. It is intended to be run on the wallet server as a
+user with access to the wallet database and configuration, but can also be
+made available via remctl to users who should have reporting privileges.
+
+This program is a fairly thin wrapper around Wallet::Report that
+translates command strings into method calls and returns the results.
+
+=head1 OPTIONS
+
+B<wallet-report> takes no traditional options.
+
+=head1 COMMANDS
+
+=over 4
+
+=item acls
+
+=item acls empty
+
+=item acls entry <scheme> <identifier>
+
+Returns a list of ACLs in the database. ACLs will be listed in the form:
+
+ <name> (ACL ID: <id>)
+
+where <name> is the human-readable name and <id> is the numeric ID. The
+numeric ID is what's used internally by the wallet system. There will be
+one line per ACL.
+
+If no search type is given, all the ACLs in the database will be returned.
+If a search type (and possible search arguments) are given, then the ACLs
+will be limited to those that match the search.
+
+The currently supported ACL search types are:
+
+=over 4
+
+=item acls empty
+
+Returns all ACLs which have no entries, generally so that abandoned ACLs
+can be destroyed.
+
+=item acls entry <scheme> <identifier>
+
+Returns all ACLs containing an entry with given scheme and identifier.
+The scheme must be an exact match, but the <identifier> string will match
+any identifier containing that string.
+
+=back
+
+=item objects
+
+=item objects acl <acl>
+
+=item objects flag <flag>
+
+=item objects owner <owner>
+
+=item objects type <type>
+
+Returns a list of objects in the database. Objects will be listed in the
+form:
+
+ <type> <name>
+
+There will be one line per object.
+
+If no search type is given, all objects in the database will be returned.
+If a search type (and possible search arguments) are given, the objects
+will be limited to those that match the search.
+
+The currently supported object search types are:
+
+=over 4
+
+=item list objects acl <acl>
+
+Returns all objects for which the given ACL name or ID has any
+permissions. This includes those objects owned by the ACL as well as
+those where that ACL has any other, more limited permissions.
+
+=item list objects flag <flag>
+
+Returns all objects which have the given flag set.
+
+=item list objects owner <acl>
+
+Returns all objects owned by the given ACL name or ID.
+
+=item list objects type <type>
+
+Returns all objects of the given type.
+
+=back
+
+=item owners <type-pattern> <name-pattern>
+
+Returns a list of all ACL entries in owner ACLs for all objects matching
+both <type-pattern> and <name-pattern>. These can be the type or name of
+objects or they can be patterns using C<%> as the wildcard character
+following the normal rules of SQL patterns.
+
+The output will be one line per ACL line in the form:
+
+ <scheme> <identifier>
+
+with duplicates suppressed.
+
+=back
+
+=head1 SEE ALSO
+
+Wallet::Config(3), Wallet::Report(3), wallet-backend(8)
+
+This program is part of the wallet system. The current version is
+available from L<http://www.eyrie.org/~eagle/software/wallet/>.
+
+=head1 AUTHOR
+
+Russ Allbery <rra@stanford.edu>
+
+=cut
diff --git a/server/wallet-report.8 b/server/wallet-report.8
new file mode 100644
index 0000000..147617a
--- /dev/null
+++ b/server/wallet-report.8
@@ -0,0 +1,253 @@
+.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "WALLET-REPORT 8"
+.TH WALLET-REPORT 8 "2010-02-20" "0.10" "wallet"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+wallet\-report \- Wallet server reporting interface
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+\&\fBwallet-report\fR \fItype\fR [\fIargs\fR ...]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\fBwallet-report\fR provides a command-line interface for running reports on
+the wallet database. It is intended to be run on the wallet server as a
+user with access to the wallet database and configuration, but can also be
+made available via remctl to users who should have reporting privileges.
+.PP
+This program is a fairly thin wrapper around Wallet::Report that
+translates command strings into method calls and returns the results.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fBwallet-report\fR takes no traditional options.
+.SH "COMMANDS"
+.IX Header "COMMANDS"
+.IP "acls" 4
+.IX Item "acls"
+.PD 0
+.IP "acls empty" 4
+.IX Item "acls empty"
+.IP "acls entry <scheme> <identifier>" 4
+.IX Item "acls entry <scheme> <identifier>"
+.PD
+Returns a list of ACLs in the database. ACLs will be listed in the form:
+.Sp
+.Vb 1
+\& <name> (ACL ID: <id>)
+.Ve
+.Sp
+where <name> is the human-readable name and <id> is the numeric \s-1ID\s0. The
+numeric \s-1ID\s0 is what's used internally by the wallet system. There will be
+one line per \s-1ACL\s0.
+.Sp
+If no search type is given, all the ACLs in the database will be returned.
+If a search type (and possible search arguments) are given, then the ACLs
+will be limited to those that match the search.
+.Sp
+The currently supported \s-1ACL\s0 search types are:
+.RS 4
+.IP "acls empty" 4
+.IX Item "acls empty"
+Returns all ACLs which have no entries, generally so that abandoned ACLs
+can be destroyed.
+.IP "acls entry <scheme> <identifier>" 4
+.IX Item "acls entry <scheme> <identifier>"
+Returns all ACLs containing an entry with given scheme and identifier.
+The scheme must be an exact match, but the <identifier> string will match
+any identifier containing that string.
+.RE
+.RS 4
+.RE
+.IP "objects" 4
+.IX Item "objects"
+.PD 0
+.IP "objects acl <acl>" 4
+.IX Item "objects acl <acl>"
+.IP "objects flag <flag>" 4
+.IX Item "objects flag <flag>"
+.IP "objects owner <owner>" 4
+.IX Item "objects owner <owner>"
+.IP "objects type <type>" 4
+.IX Item "objects type <type>"
+.PD
+Returns a list of objects in the database. Objects will be listed in the
+form:
+.Sp
+.Vb 1
+\& <type> <name>
+.Ve
+.Sp
+There will be one line per object.
+.Sp
+If no search type is given, all objects in the database will be returned.
+If a search type (and possible search arguments) are given, the objects
+will be limited to those that match the search.
+.Sp
+The currently supported object search types are:
+.RS 4
+.IP "list objects acl <acl>" 4
+.IX Item "list objects acl <acl>"
+Returns all objects for which the given \s-1ACL\s0 name or \s-1ID\s0 has any
+permissions. This includes those objects owned by the \s-1ACL\s0 as well as
+those where that \s-1ACL\s0 has any other, more limited permissions.
+.IP "list objects flag <flag>" 4
+.IX Item "list objects flag <flag>"
+Returns all objects which have the given flag set.
+.IP "list objects owner <acl>" 4
+.IX Item "list objects owner <acl>"
+Returns all objects owned by the given \s-1ACL\s0 name or \s-1ID\s0.
+.IP "list objects type <type>" 4
+.IX Item "list objects type <type>"
+Returns all objects of the given type.
+.RE
+.RS 4
+.RE
+.IP "owners <type\-pattern> <name\-pattern>" 4
+.IX Item "owners <type-pattern> <name-pattern>"
+Returns a list of all \s-1ACL\s0 entries in owner ACLs for all objects matching
+both <type\-pattern> and <name\-pattern>. These can be the type or name of
+objects or they can be patterns using \f(CW\*(C`%\*(C'\fR as the wildcard character
+following the normal rules of \s-1SQL\s0 patterns.
+.Sp
+The output will be one line per \s-1ACL\s0 line in the form:
+.Sp
+.Vb 1
+\& <scheme> <identifier>
+.Ve
+.Sp
+with duplicates suppressed.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIWallet::Config\fR\|(3), \fIWallet::Report\fR\|(3), \fIwallet\-backend\fR\|(8)
+.PP
+This program is part of the wallet system. The current version is
+available from <http://www.eyrie.org/~eagle/software/wallet/>.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Russ Allbery <rra@stanford.edu>
diff --git a/tests/TESTS b/tests/TESTS
index c94cce0..161941c 100644
--- a/tests/TESTS
+++ b/tests/TESTS
@@ -1,16 +1,18 @@
client/basic
client/full
-client/pod
client/prompt
-kasetkey/basic
+docs/pod
+docs/pod-spelling
portable/asprintf
+portable/mkstemp
+portable/setenv
portable/snprintf
portable/strlcat
portable/strlcpy
server/admin
server/backend
server/keytab
-server/pod
util/concat
util/messages
+util/messages-krb5
util/xmalloc
diff --git a/tests/client/basic-t.in b/tests/client/basic-t.in
index f18c28e..1ae3a70 100644
--- a/tests/client/basic-t.in
+++ b/tests/client/basic-t.in
@@ -1,56 +1,23 @@
#! /bin/sh
-# $Id$
#
# Test suite for the wallet command-line client.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2006, 2007, 2008, 2010
+# Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
# Load the test library.
-. "@abs_top_srcdir@/tests/libtest.sh"
-
-# Print the number of tests.
-total=35
-count=1
-echo "$total"
-
-# Find the client program.
-chdir_data '../client/wallet'
-if [ ! -f 'data/test.keytab' ] || [ -z '@REMCTLD@' ] ; then
- skip 1 "$total" 'no Kerberos configuration'
- exit 0
-fi
-wallet='../client/wallet'
-
-# Start the remctld daemon and wait for it to start.
-principal=`cat data/test.principal`
-rm -f data/pid
-( @REMCTLD@ -m -p 14373 -s "$principal" -P data/pid -f data/basic.conf \
- -S -F -k data/test.keytab &)
-KRB5CCNAME=data/test.cache; export KRB5CCNAME
-kinit -k -t data/test.keytab "$principal" > /dev/null 2>&1
-if [ $? != 0 ] ; then
- kinit -t data/test.keytab "$principal" > /dev/null 2>&1
-fi
-if [ $? != 0 ] ; then
- kinit -T /bin/true -k -K data/test.keytab "$principal" > /dev/null 2>&1
-fi
-if [ $? != 0 ] ; then
- echo 'Unable to obtain Kerberos tickets' >&2
- exit 1
-fi
-[ -f data/pid ] || sleep 1
-if [ ! -f data/pid ] ; then
- echo 'remctld did not start' >&2
- exit 1
-fi
-
-# We need a modified krb5.conf file for the srvtab test to work, since we need
-# to add a v4_realm setting for the test-k5.stanford.edu realm that the keytab
-# is for. Despite all the Stanford hard-coding, this test isn't
-# Stanford-specific. It just matches the data files shipped with the package.
+. "$SOURCE/tap/libtap.sh"
+. "$SOURCE/tap/kerberos.sh"
+. "$SOURCE/tap/remctl.sh"
+cd "$SOURCE"
+
+# We need a modified krb5.conf file to test wallet configuration settings in
+# krb5.conf. Despite the hard-coding of test-k5.stanford.edu, this test isn't
+# Stanford-specific; it just matches the files that are distributed with the
+# package.
krb5conf=
for p in /etc/krb5.conf /usr/local/etc/krb5.conf data/krb5.conf ; do
if [ -r "$p" ] ; then
@@ -64,7 +31,7 @@ for p in /etc/krb5.conf /usr/local/etc/krb5.conf data/krb5.conf ; do
[realms]
test-k5.stanford.edu = {
- v4_realm = TEST.STANFORD.EDU
+ v4_realm = test-k5.stanford.edu
}
EOF
KRB5_CONFIG="./krb5.conf"
@@ -73,44 +40,39 @@ EOF
fi
done
if [ -z "$krb5conf" ] ; then
- echo 'No krb5.conf found -- put one in tests/data/krb5.conf' >&2
- exit 1
+ skip_all 'no krb5.conf found, put one in tests/data/krb5.conf'
fi
+# Test setup.
+kerberos_setup
+if [ $? != 0 ] ; then
+ skip_all 'Kerberos tests not configured'
+elif [ -z '@REMCTLD@' ] ; then
+ skip_all 'No remctld found'
+else
+ plan 36
+fi
+remctld_start '@REMCTLD@' "$SOURCE/data/basic.conf"
+wallet="$BUILD/../client/wallet"
+
# Make sure everything's clean.
-rm -f output output.bak keytab keytab.bak srvtab srvtab.bak sync-kaserver \
- autocreated
+rm -f output output.bak keytab keytab.bak srvtab srvtab.bak autocreated
# Now, we can finally run our tests. First, basic operations.
-runsuccess "" "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet \
- -f output get file fake-test
-if cmp output data/fake-data >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
-if [ -f output.bak ] || [ -f output.new ] ; then
- printcount "not ok"
-else
- printcount "ok"
-fi
-if [ -f autocreated ] ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
-runsuccess "" "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet \
- -f output get file fake-test
-if cmp output data/fake-data >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
-if [ -f output.new ] || [ ! -f output.bak ] ; then
- printcount "not ok"
-else
- printcount "ok"
-fi
+ok_program 'get file' 0 '' \
+ "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet -f output \
+ get file fake-test
+ok '...and file is correct' cmp output data/fake-data
+ok '...and no backup files' [ ! -f output.bak ]
+ok '...and no new files' [ ! -f output.new ]
+ok '...and we tried autocreation' [ -f autocreated ]
+ok_program 'get file again' 0 '' \
+ "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet -f output \
+ get file fake-test
+ok '...and file is correct' cmp output data/fake-data
+ok '...and now there is a backup file' [ -f output.bak ]
+ok '...which has the right contents' cmp output.bak data/fake-data
+ok '...but there is no new file' [ ! -f output.new ]
# Now, append configuration to krb5.conf and test getting configuration from
# there.
@@ -124,138 +86,86 @@ cat >> krb5.conf <<EOF
wallet_principal = $principal
}
EOF
-runsuccess "" "$wallet" -f output get file fake-test
-if cmp output data/fake-data >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
+ok_program 'get file with configuration' 0 '' \
+ "$wallet" -f output get file fake-test
+ok '...and file is correct' cmp output data/fake-data
rm -f output output.bak
# Test keytab support.
-runsuccess "" "$wallet" -f keytab get keytab service/fake-srvtab
-if cmp keytab data/fake-keytab >/dev/null 2>&1 ; then
- printcount "ok"
- rm keytab
-else
- printcount "not ok"
-fi
-if [ ! -f sync-kaserver ] ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
+ok_program 'get keytab' 0 '' \
+ "$wallet" -f keytab get keytab service/fake-srvtab
+ok '...and keytab is correct' cmp keytab data/fake-keytab
+rm -f keytab
# Test srvtab support.
-runsuccess "" "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab
-if cmp keytab data/fake-keytab >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
-rm keytab
-if [ -f sync-kaserver ] ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
-runsuccess "" "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab
-if cmp keytab data/fake-keytab >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
-if [ -f sync-kaserver ] ; then
- printcount "ok"
- rm sync-kaserver
-else
- printcount "not ok"
-fi
-if cmp srvtab data/fake-srvtab >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
-if cmp srvtab.bak data/fake-srvtab >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
+ok_program 'get srvtab' 0 '' \
+ "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab
+ok '...and keytab is correct' cmp keytab data/fake-keytab
+rm -f keytab
+ok_program 'get srvtab again' 0 '' \
+ "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab
+ok '...and keytab is correct' cmp keytab data/fake-keytab
+ok '...and srvtab is correct' cmp srvtab data/fake-srvtab
+ok '...and srvtab backup is correct' cmp srvtab.bak data/fake-srvtab
rm -f srvtab srvtab.bak
# Test keytab merging.
-runsuccess "" "$wallet" -f keytab get keytab service/fake-keytab
+ok_program 'keytab merging' 0 '' \
+ "$wallet" -f keytab get keytab service/fake-keytab
(klist -keK keytab 2>&1) | sed '/Keytab name:/d' > klist-seen
(klist -keK data/fake-keytab-merge 2>&1) | sed '/Keytab name:/d' > klist-good
-if cmp klist-seen klist-good >/dev/null 2>&1 ; then
- printcount "ok"
- rm -f keytab klist-seen klist-good
-else
- printcount "not ok"
-fi
+ok '...and the merged keytab is correct' cmp klist-seen klist-good
+rm -f keytab klist-seen klist-good
# Test srvtab download into a merged keytab with an older version.
cp data/fake-keytab-old keytab
-runsuccess "" "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab
-if [ -f sync-kaserver ] ; then
- printcount "ok"
- rm sync-kaserver
-else
- printcount "not ok"
-fi
-if cmp srvtab data/fake-srvtab >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
+ok_program 'keytab merging with srvtab creation' 0 '' \
+ "$wallet" -f keytab -S srvtab get keytab service/fake-srvtab
+ok '...and the srvtab is correct' cmp srvtab data/fake-srvtab
rm -f keytab srvtab
# Test store from standard input.
-echo "This is a test of store" | runsuccess "" "$wallet" store file fake-test
-count=`expr $count + 1`
+echo "This is a test of store" > input
+ok_program 'store from stdin' 0 '' "$wallet" store file fake-test < input
+rm -f input
echo "file fake-test" > store-correct
echo "This is a test of store" >> store-correct
-if cmp store-output store-correct >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
- echo == store-output ==
- cat store-output
- echo == store-correct ==
- cat store-correct
-fi
+ok '...and the correct data was stored' diff store-output store-correct
rm -f store-output store-correct
# Test store with -f.
echo "This is more store input" > store-input
echo "file fake-test" > store-correct
cat store-input >> store-correct
-runsuccess "" "$wallet" -f store-input store file fake-test
-if cmp store-output store-correct >/dev/null 2>&1 ; then
- printcount "ok"
-else
- printcount "not ok"
-fi
+ok_program 'store from a file' 0 '' \
+ "$wallet" -f store-input store file fake-test
+ok '...and the correct data was stored' cmp store-output store-correct
+rm -f store-input store-output store-correct
+printf 'This is store input\000with a nul character' > store-input
+echo 'file fake-nul' > store-correct
+cat store-input >> store-correct
+ok_program 'store from a file with a nul' 0 '' \
+ "$wallet" -f store-input store file fake-nul
+ok '...and the correct data was stored' cmp store-output store-correct
rm -f store-input store-output store-correct
# Test various other client functions and errors.
-runsuccess "This is a fake keytab." "$wallet" get keytab service/fake-output
-runsuccess "Some stuff about file fake-test" \
+ok_program 'get output to stdout' 0 'This is a fake keytab.' \
+ "$wallet" get keytab service/fake-output
+ok_program 'show output' 0 'Some stuff about file fake-test' \
"$wallet" show file fake-test
-runfailure 1 "wallet: Unknown object type srvtab" \
+ok_program 'unknown object type' 1 'wallet: Unknown object type srvtab' \
"$wallet" get srvtab service/fake-test
-runfailure 1 "wallet: Unknown keytab service/unknown" \
+ok_program 'unknown keytab name in show' 1 \
+ 'wallet: Unknown keytab service/unknown' \
"$wallet" show keytab service/unknown
-runfailure 1 "wallet: Unknown keytab service/unknown" \
+ok_program 'unknown keytab name in get' 1 \
+ 'wallet: Unknown keytab service/unknown' \
"$wallet" get keytab service/unknown
-runsuccess "Expiration date of keytab service/fake-test" \
+ok_program 'expiration date' 0 'Expiration date of keytab service/fake-test' \
"$wallet" expires keytab service/fake-test
# Clean up.
-KRB5_CONFIG=
-rm krb5.conf
-rm -f autocreated data/test.cache
-if [ -f data/pid ] ; then
- kill `cat data/pid`
- rm -f data/pid
-fi
+rm -f autocreated krb5.conf
+remctld_stop
+kerberos_cleanup
diff --git a/tests/client/full-t.in b/tests/client/full-t.in
index f4ef1d3..ce2789d 100644
--- a/tests/client/full-t.in
+++ b/tests/client/full-t.in
@@ -1,24 +1,23 @@
#!/usr/bin/perl -w
-# $Id$
#
-# tests/client/full-t -- End-to-end tests for the wallet client.
+# End-to-end tests for the wallet client.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
# Point to our server configuration. This must be done before Wallet::Config
# is loaded, and it's pulled in as a prerequisite for Wallet::Admin.
-BEGIN { $ENV{WALLET_CONFIG} = '@abs_top_srcdir@/tests/data/wallet.conf' }
+BEGIN { $ENV{WALLET_CONFIG} = "$ENV{SOURCE}/data/wallet.conf" }
-BEGIN { our $total = 53 }
+BEGIN { our $total = 59 }
use Test::More tests => $total;
-use lib '@abs_top_srcdir@/perl';
+use lib "$ENV{SOURCE}/../perl";
use Wallet::Admin;
-use lib '@abs_top_srcdir@/perl/t/lib';
+use lib "$ENV{SOURCE}/../perl/t/lib";
use Util;
# Make a call to the wallet client. Takes the principal used by the server
@@ -34,9 +33,9 @@ sub wallet {
or die "cannot create wallet.out: $!\n";
open (STDERR, '>', 'wallet.err')
or die "cannot create wallet.err: $!\n";
- exec ('@abs_top_builddir@/client/wallet', '-k', $principal, '-p',
+ exec ("$ENV{BUILD}/../client/wallet", '-k', $principal, '-p',
'14373', '-s', 'localhost', @command)
- or die "cannot run @abs_top_builddir@/client/wallet: $!\n";
+ or die "cannot run $ENV{BUILD}/client/wallet: $!\n";
} else {
waitpid ($pid, 0);
}
@@ -52,21 +51,24 @@ sub wallet {
return ($output, $error, $status);
}
+# cd to the correct directory.
+chdir "$ENV{SOURCE}" or die "Cannot chdir to $ENV{SOURCE}: $!\n";
+
SKIP: {
skip 'no keytab configuration', $total
- unless -f '@abs_top_builddir@/tests/data/test.keytab';
+ unless -f "$ENV{BUILD}/data/test.keytab";
my $remctld = '@REMCTLD@';
skip 'remctld not found', $total unless $remctld;
# Spawn remctld and get local tickets. Don't destroy the user's Kerberos
# ticket cache.
unlink ('krb5cc_test', 'test-pid');
- my $principal = contents ('@abs_top_builddir@/tests/data/test.principal');
+ my $principal = contents ("$ENV{BUILD}/data/test.principal");
remctld_spawn ($remctld, $principal,
- '@abs_top_builddir@/tests/data/test.keytab',
- '@abs_top_builddir@/tests/data/full.conf');
+ "$ENV{BUILD}/data/test.keytab",
+ "$ENV{SOURCE}/data/full.conf");
$ENV{KRB5CCNAME} = 'krb5cc_test';
- getcreds ('@abs_top_builddir@/tests/data/test.keytab', $principal);
+ getcreds ("$ENV{BUILD}/data/test.keytab", $principal);
# Use Wallet::Admin to set up the database.
db_setup;
@@ -166,6 +168,22 @@ SKIP: {
is ($out, '-q', ' with the right output');
is ($err, '', ' and no error');
+ # Store data containing nul characters.
+ my $data = "Some data\000with a nul";
+ open (IN, '>', 'tmp-file') or BAIL_OUT ("cannot create tmp-file: $!");
+ print IN $data;
+ close IN;
+ ($out, $err, $status) = wallet ($principal, '-f', 'tmp-file', 'store',
+ 'file', 'auto');
+ unlink ('tmp-file');
+ is ($status, 0, 'Storing data with a nul succeeds');
+ is ($out, '', ' with no output');
+ is ($err, '', ' and no error');
+ ($out, $err, $status) = wallet ($principal, 'get', 'file', 'auto');
+ is ($status, 0, 'Object get succeeds');
+ is ($out, $data, ' with the right output');
+ is ($err, '', ' and no error');
+
# All done.
remctld_stop;
$admin->destroy;
diff --git a/tests/client/pod-t.in b/tests/client/pod-t.in
deleted file mode 100644
index 98c34c7..0000000
--- a/tests/client/pod-t.in
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/perl
-# $Id$
-#
-# Test POD formatting for client documentation.
-#
-# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
-#
-# See LICENSE for licensing terms.
-
-use Test::More;
-
-my @files = qw(wallet.pod);
-my $total = scalar (@files);
-plan tests => $total;
-
-eval 'use Test::Pod 1.00';
-SKIP: {
- skip $total, 'Test::Pod 1.00 required for testing POD' if $@;
- for my $file (@files) {
- pod_file_ok ("@abs_top_srcdir@/client/$file", "client/$file");
- }
-}
diff --git a/tests/client/prompt-t.in b/tests/client/prompt-t.in
index 2d6097d..1d8b079 100644
--- a/tests/client/prompt-t.in
+++ b/tests/client/prompt-t.in
@@ -1,29 +1,27 @@
#!/usr/bin/perl -w
-# $Id$
#
-# tests/client/prompt-t -- Password prompting tests for the wallet client.
+# Password prompting tests for the wallet client.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
BEGIN { our $total = 5 }
use Test::More tests => $total;
-use lib '@abs_top_srcdir@/perl';
+use lib "$ENV{SOURCE}/..//perl";
use Wallet::Admin;
-use lib '@abs_top_srcdir@/perl/t/lib';
+use lib "$ENV{SOURCE}/../perl/t/lib";
use Util;
# cd to the correct directory.
-chdir '@abs_top_srcdir@/tests'
- or die "Cannot chdir to @abs_top_srcdir@/tests: $!\n";
+chdir "$ENV{SOURCE}" or die "Cannot chdir to $ENV{SOURCE}: $!\n";
SKIP: {
skip 'no password configuration', $total
- unless -f '@abs_top_builddir@/tests/data/test.password';
+ unless -f "$ENV{BUILD}/data/test.password";
my $remctld = '@REMCTLD@';
skip 'remctld not found', $total unless $remctld;
eval { require Expect };
@@ -36,22 +34,21 @@ SKIP: {
# Spawn remctld and set up with a different ticket cache.
unlink ('krb5cc_test', 'test-pid');
- my $principal = contents ('@abs_top_builddir@/tests/data/test.principal');
- remctld_spawn ($remctld, $principal,
- '@abs_top_builddir@/tests/data/test.keytab',
- '@abs_top_builddir@/tests/data/basic.conf');
+ my $principal = contents ("$ENV{BUILD}/data/test.principal");
+ remctld_spawn ($remctld, $principal, "$ENV{BUILD}/data/test.keytab",
+ "$ENV{SOURCE}/data/basic.conf");
$ENV{KRB5CCNAME} = 'krb5cc_test';
# Read in the principal and password.
- open (PASS, '<', '@abs_top_builddir@/tests/data/test.password')
- or die "Cannot open @abs_top_builddir@/tests/data/test.password: $!\n";
+ open (PASS, '<', "$ENV{BUILD}/data/test.password")
+ or die "Cannot open $ENV{BUILD}/data/test.password: $!\n";
my $user = <PASS>;
my $password = <PASS>;
close PASS;
chomp ($user, $password);
# Spawn wallet and check an invalid password.
- my $wallet = Expect->spawn ('@abs_top_builddir@/client/wallet', '-k',
+ my $wallet = Expect->spawn ("$ENV{BUILD}/../client/wallet", '-k',
$principal, '-p', 14373, '-s', 'localhost',
'-c', 'fake-wallet', '-u', $user, 'get',
'keytab', 'service/fake-output');
@@ -62,7 +59,7 @@ SKIP: {
$wallet->soft_close;
# Now check a valid password.
- $wallet = Expect->spawn ('@abs_top_builddir@/client/wallet', '-k',
+ $wallet = Expect->spawn ("$ENV{BUILD}/../client/wallet", '-k',
$principal, '-p', 14373, '-s', 'localhost',
'-c', 'fake-wallet', '-u', $user, 'get',
'keytab', 'service/fake-output');
diff --git a/tests/data/basic.conf b/tests/data/basic.conf
index 7ad998f..5f3c2a3 100644
--- a/tests/data/basic.conf
+++ b/tests/data/basic.conf
@@ -1,4 +1,4 @@
# remctl configuration for wallet client tests.
-# $Id$
+fake-wallet store data/cmd-fake stdin=last ANYUSER
fake-wallet ALL data/cmd-fake ANYUSER
diff --git a/tests/data/cmd-fake b/tests/data/cmd-fake
index 3ffd9cc..add72fc 100755
--- a/tests/data/cmd-fake
+++ b/tests/data/cmd-fake
@@ -1,11 +1,10 @@
#!/bin/sh
-# $Id$
#
# This is a fake wallet backend that returns bogus data for verification by
# the client test suite. It doesn't test any of the wallet server code.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2007, 2008, 2010 Board of Trustees, Leland Stanford Jr. University
# See LICENSE for licensing terms.
command="$1"
@@ -18,55 +17,6 @@ if [ "$type" != "keytab" ] && [ "$type" != "file" ] ; then
fi
case "$command" in
-getattr)
- if [ -n "$3" ] ; then
- echo "Too many arguments" >&2
- exit 1
- fi
- if [ "$type" != "keytab" ] || [ "$2" != sync ] ; then
- echo "Unknown attribute $2" >&2
- exit 1
- fi
- case "$1" in
- service/fake-srvtab)
- if [ -f sync-kaserver ] ; then
- echo "kaserver"
- fi
- ;;
- *)
- echo "Looking at sync attribute of wrong keytab" >&2
- exit 1
- ;;
- esac
- ;;
-setattr)
- if [ -n "$4" ] ; then
- echo "Too many arguments" >&2
- exit 1
- fi
- if [ "$type" != "keytab" ] || [ "$2" != sync ] ; then
- echo "Unknown attribute $2" >&2
- exit 1
- fi
- case "$1" in
- service/fake-srvtab)
- if [ "$3" = "kaserver" ] ; then
- touch sync-kaserver
- else
- if [ "$3" = "" ] ; then
- rm sync-kaserver
- else
- echo "Invalid attribute value $3" >&2
- exit 1
- fi
- fi
- ;;
- *)
- echo "Looking at sync attribute of wrong keytab" >&2
- exit 1
- ;;
- esac
- ;;
check)
if [ -n "$2" ] ; then
echo "Too many arguments" >&2
@@ -132,10 +82,15 @@ get)
;;
store)
if [ -n "$3" ] ; then
- echo "Too many arguments" >&2
+ echo 'Too many arguments' >&2
+ exit 1
+ fi
+ if [ -n "$2" ] ; then
+ echo 'stdin remctld configuration not supported' >&2
exit 1
fi
- printf "$type $1\n$2" > store-output
+ printf "$type $1\n" > store-output
+ cat >> store-output
;;
show)
if [ -n "$2" ] ; then
diff --git a/tests/data/cmd-wrapper.in b/tests/data/cmd-wrapper
index e119002..79b1943 100644..100755
--- a/tests/data/cmd-wrapper.in
+++ b/tests/data/cmd-wrapper
@@ -1,10 +1,8 @@
#!/bin/sh
-# $Id$
#
# Wrapper around the standard wallet-backend script that sets the Perl INC
# path and the WALLET_CONFIG environment variable appropriately.
-WALLET_CONFIG='@abs_top_srcdir@/tests/data/wallet.conf'
+WALLET_CONFIG="$SOURCE/data/wallet.conf"
export WALLET_CONFIG
-exec perl -I'@abs_top_srcdir@/perl' '@abs_top_srcdir@/server/wallet-backend' \
- -q "$@"
+exec perl -I"$SOURCE/../perl" "$SOURCE/../server/wallet-backend" -q "$@"
diff --git a/tests/data/fake-kadmin b/tests/data/fake-kadmin
index 81dc999..61906a4 100755
--- a/tests/data/fake-kadmin
+++ b/tests/data/fake-kadmin
@@ -1,5 +1,4 @@
#!/usr/bin/perl -w
-# $Id$
#
# fake-kadmin -- Fake kadmin.local used to test the keytab backend.
#
diff --git a/tests/data/fake-srvtab b/tests/data/fake-srvtab
index 3c0ec65..f454af2 100644
--- a/tests/data/fake-srvtab
+++ b/tests/data/fake-srvtab
Binary files differ
diff --git a/tests/data/full.conf b/tests/data/full.conf
new file mode 100644
index 0000000..941a9ac
--- /dev/null
+++ b/tests/data/full.conf
@@ -0,0 +1,4 @@
+# remctl configuration for full wallet client tests.
+
+wallet store data/cmd-wrapper stdin=4 ANYUSER
+wallet ALL data/cmd-wrapper ANYUSER
diff --git a/tests/data/full.conf.in b/tests/data/full.conf.in
deleted file mode 100644
index b97a4bc..0000000
--- a/tests/data/full.conf.in
+++ /dev/null
@@ -1,4 +0,0 @@
-# remctl configuration for full wallet client tests.
-# $Id$
-
-wallet ALL @abs_top_builddir@/tests/data/cmd-wrapper ANYUSER
diff --git a/tests/data/wallet.conf b/tests/data/wallet.conf
index b864e5e..0a232dd 100644
--- a/tests/data/wallet.conf
+++ b/tests/data/wallet.conf
@@ -1,5 +1,4 @@
# wallet.conf -- Test wallet server configuration. -*- perl -*-
-# $Id$
# Always test with SQLite.
$DB_DRIVER = 'SQLite';
diff --git a/tests/docs/pod-spelling-t b/tests/docs/pod-spelling-t
new file mode 100755
index 0000000..6993e4c
--- /dev/null
+++ b/tests/docs/pod-spelling-t
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+#
+# Check for spelling errors in POD documentation
+#
+# Checks all POD files in the tree for spelling problems using Pod::Spell and
+# either aspell or ispell. aspell is preferred. This test is disabled unless
+# RRA_MAINTAINER_TESTS is set, since spelling dictionaries vary too much
+# between environments.
+#
+# Copyright 2008, 2009 Russ Allbery <rra@stanford.edu>
+#
+# See LICENSE for licensing terms.
+
+use strict;
+use Test::More;
+
+# Skip all spelling tests unless the maintainer environment variable is set.
+plan skip_all => 'spelling tests only run for maintainer'
+ unless $ENV{RRA_MAINTAINER_TESTS};
+
+# Load required Perl modules.
+eval 'use Test::Pod 1.00';
+plan skip_all => 'Test::Pod 1.00 required for testing POD' if $@;
+eval 'use Pod::Spell';
+plan skip_all => 'Pod::Spell required to test POD spelling' if $@;
+
+# Locate a spell-checker. hunspell is not currently supported due to its lack
+# of support for contractions (at least in the version in Debian).
+my @spell;
+my %options = (aspell => [ qw(-d en_US --home-dir=./ list) ],
+ ispell => [ qw(-d american -l -p /dev/null) ]);
+SEARCH: for my $program (qw/aspell ispell/) {
+ for my $dir (split ':', $ENV{PATH}) {
+ if (-x "$dir/$program") {
+ @spell = ("$dir/$program", @{ $options{$program} });
+ }
+ last SEARCH if @spell;
+ }
+}
+plan skip_all => 'aspell or ispell required to test POD spelling'
+ unless @spell;
+
+# Prerequisites are satisfied, so we're going to do some testing. Figure out
+# what POD files we have and from that develop our plan.
+$| = 1;
+my @pod = map {
+ my $pod = "$ENV{SOURCE}/../" . $_;
+ $pod =~ s,[^/.][^/]*/../,,g;
+ $pod;
+} qw(client/wallet.pod server/keytab-backend server/wallet-admin
+ server/wallet-backend server/wallet-report);
+plan tests => scalar @pod;
+
+# Finally, do the checks.
+for my $pod (@pod) {
+ my $child = open (CHILD, '-|');
+ if (not defined $child) {
+ BAIL_OUT ("cannot fork: $!");
+ } elsif ($child == 0) {
+ my $pid = open (SPELL, '|-', @spell)
+ or BAIL_OUT ("cannot run @spell: $!");
+ open (POD, '<', $pod) or BAIL_OUT ("cannot open $pod: $!");
+ my $parser = Pod::Spell->new;
+ $parser->parse_from_filehandle (\*POD, \*SPELL);
+ close POD;
+ close SPELL;
+ exit ($? >> 8);
+ } else {
+ my @words = <CHILD>;
+ close CHILD;
+ SKIP: {
+ skip "@spell failed for $pod", 1 unless $? == 0;
+ for (@words) {
+ s/^\s+//;
+ s/\s+$//;
+ }
+ is ("@words", '', $pod);
+ }
+ }
+}
diff --git a/tests/docs/pod-t b/tests/docs/pod-t
new file mode 100755
index 0000000..f92ba2c
--- /dev/null
+++ b/tests/docs/pod-t
@@ -0,0 +1,21 @@
+#!/usr/bin/perl -w
+#
+# Test POD formatting for documentation.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+use strict;
+use Test::More;
+eval 'use Test::Pod 1.00';
+plan skip_all => 'Test::Pod 1.00 required for testing POD' if $@;
+
+my @files = qw(client/wallet.pod server/keytab-backend server/wallet-admin
+ server/wallet-backend server/wallet-report);
+my $total = scalar (@files);
+plan tests => $total;
+for my $file (@files) {
+ pod_file_ok ("$ENV{SOURCE}/../$file", $file);
+}
diff --git a/tests/kasetkey/basic-t.in b/tests/kasetkey/basic-t.in
deleted file mode 100644
index afc6747..0000000
--- a/tests/kasetkey/basic-t.in
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/perl -w
-# $Id$
-#
-# Tests for basic kasetkey functionality.
-#
-# We only test creation (with a random key), deletion, enable, disable, and
-# examine. That's enough to verify that kasetkey is basically working, and
-# since AFS kaservers are becoming scarce, it's probably not worth the effort
-# to do anything more comprehensive.
-#
-# We do test creation of a principal with a known key given a srvtab from
-# inside the wallet server test suite already.
-#
-# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
-#
-# See LICENSE for licensing terms.
-
-BEGIN { our $total = 27 }
-use Test::More tests => $total;
-
-use lib '@abs_top_builddir@/perl/blib/lib';
-use lib '@abs_top_srcdir@/perl/t/lib';
-use Util;
-
-# Global variables used for the kasetkey configuration.
-our $ADMIN;
-our $SRVTAB;
-
-# Make a call to the kasetkey client and returns the standard output, the
-# standard error, and the exit status as a list.
-sub kasetkey {
- my @command = @_;
- my $pid = fork;
- if (not defined $pid) {
- die "cannot fork: $!\n";
- } elsif ($pid == 0) {
- open (STDOUT, '>', 'kasetkey.out')
- or die "cannot create kasetkey.out: $!\n";
- open (STDERR, '>', 'kasetkey.err')
- or die "cannot create kasetkey.err: $!\n";
- exec ('@abs_top_builddir@/kasetkey/kasetkey', '-a', $ADMIN,
- '-k', $SRVTAB, @command)
- or die "cannot run @abs_top_builddir@/kasetkey/kasetky: $!\n";
- } else {
- waitpid ($pid, 0);
- }
- my $status = ($? >> 8);
- local $/;
- open (OUT, '<', 'kasetkey.out') or die "cannot open kasetkey.out: $!\n";
- my $output = <OUT>;
- close OUT;
- open (ERR, '<', 'kasetkey.err') or die "cannot open kasetkey.err: $!\n";
- my $error = <ERR>;
- close ERR;
- unlink ('kasetkey.out', 'kasetkey.err');
- return ($output, $error, $status);
-}
-
-SKIP: {
- skip 'no AFS kaserver configuration', $total
- unless -f '@abs_top_builddir@/tests/data/test.srvtab';
- skip 'no AFS kaserver support', $total,
- unless -x '@abs_top_builddir@/kasetkey/kasetkey';
-
- # Set up the configuration.
- $ADMIN = contents ('@abs_top_builddir@/tests/data/test.admin');
- $SRVTAB = '@abs_top_builddir@/tests/data/test.srvtab';
- my $realm = $ADMIN;
- $realm =~ s/^[^\@]+\@//;
- my $principal = "wallet.one\@$realm";
-
- # Now we can start manipulating principals. Test examine and create.
- my ($out, $err, $status) = kasetkey ('-e', $principal);
- is ($status, 1, 'Examining a non-existent principal fails');
- is ($out, '', ' with no output');
- is ($err, "no such entry in the database\n", ' and the right error');
- ($out, $err, $status) = kasetkey ('-s', $principal, '-r');
- is ($status, 0, 'Creating a principal succeeds');
- is ($out, '', ' with no output');
- is ($err, '', ' and no error');
- ($out, $err, $status) = kasetkey ('-e', $principal);
- is ($status, 0, 'Examining a principal succeeds');
- $out =~ s/: (Sun|Mon|Tue|Wed|Thu|Fri|Sat).*/: DATE/g;
- my $shortadmin = $ADMIN;
- $shortadmin =~ s/\@.*//;
- my $enabled = <<"EOE";
-status: enabled
-account expiration: never
-password last changed: DATE
-modification time: DATE
-modified by: $shortadmin
-EOE
- is ($out, $enabled, ' with the right output');
- is ($err, '', ' and no error');
-
- # Test enable and disable.
- ($out, $err, $status) = kasetkey ('-s', $principal, '-n');
- is ($status, 0, 'Disabling a principal succeeds');
- is ($out, '', ' with no output');
- is ($err, '', ' and no error');
- ($out, $err, $status) = kasetkey ('-e', $principal);
- is ($status, 0, ' and examining it still succeeds');
- $out =~ s/: (Sun|Mon|Tue|Wed|Thu|Fri|Sat).*/: DATE/g;
- my $disabled = $enabled;
- $disabled =~ s/enabled/disabled/;
- is ($out, $disabled, ' with the right output');
- is ($err, '', ' and no error');
- ($out, $err, $status) = kasetkey ('-s', $principal, '-t');
- is ($status, 0, 'Enabling a principal succeeds');
- is ($out, '', ' with no output');
- is ($err, '', ' and no error');
- ($out, $err, $status) = kasetkey ('-e', $principal);
- is ($status, 0, ' and examining it still succeeds');
- $out =~ s/: (Sun|Mon|Tue|Wed|Thu|Fri|Sat).*/: DATE/g;
- is ($out, $enabled, ' with the right output');
- is ($err, '', ' and no error');
-
- # Test deletion.
- ($out, $err, $status) = kasetkey ('-D', $principal);
- is ($status, 0, 'Deleting the principal succeeds');
- is ($out, '', ' with no output');
- is ($err, '', ' and no error');
- ($out, $err, $status) = kasetkey ('-e', $principal);
- is ($status, 1, ' and now examining it fails');
- is ($out, '', ' with no output');
- is ($err, "no such entry in the database\n", ' and the right error');
-}
diff --git a/tests/libtest.c b/tests/libtest.c
deleted file mode 100644
index 76d5207..0000000
--- a/tests/libtest.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/* $Id$
- *
- * Some utility routines for writing tests.
- *
- * Herein are a variety of utility routines for writing tests. All routines
- * of the form ok*() take a test number and some number of appropriate
- * arguments, check to be sure the results match the expected output using the
- * arguments, and print out something appropriate for that test number. Other
- * utility routines help in constructing more complex tests.
- *
- * Copyright 2006, 2007 Board of Trustees, Leland Stanford Jr. University
- * Copyright (c) 2004, 2005, 2006
- * by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- * 2002, 2003 by The Internet Software Consortium and Rich Salz
- *
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <config.h>
-#include <portable/system.h>
-
-#include <sys/time.h>
-#include <sys/wait.h>
-
-#include <tests/libtest.h>
-#include <util/util.h>
-
-/* A global buffer into which message_log_buffer stores error messages. */
-char *errors = NULL;
-
-
-/*
- * Initialize things. Turns on line buffering on stdout and then prints out
- * the number of tests in the test suite.
- */
-void
-test_init(int count)
-{
- if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
- syswarn("cannot set stdout to line buffered");
- printf("%d\n", count);
-}
-
-
-/*
- * Takes a boolean success value and assumes the test passes if that value
- * is true and fails if that value is false.
- */
-void
-ok(int n, int success)
-{
- printf("%sok %d\n", success ? "" : "not ", n);
-}
-
-
-/*
- * Takes an expected integer and a seen integer and assumes the test passes
- * if those two numbers match.
- */
-void
-ok_int(int n, int wanted, int seen)
-{
- if (wanted == seen)
- printf("ok %d\n", n);
- else
- printf("not ok %d\n wanted: %d\n seen: %d\n", n, wanted, seen);
-}
-
-
-/*
- * Takes a string and what the string should be, and assumes the test passes
- * if those strings match (using strcmp).
- */
-void
-ok_string(int n, const char *wanted, const char *seen)
-{
- if (wanted == NULL)
- wanted = "(null)";
- if (seen == NULL)
- seen = "(null)";
- if (strcmp(wanted, seen) != 0)
- printf("not ok %d\n wanted: %s\n seen: %s\n", n, wanted, seen);
- else
- printf("ok %d\n", n);
-}
-
-
-/*
- * Takes an expected integer and a seen integer and assumes the test passes if
- * those two numbers match.
- */
-void
-ok_double(int n, double wanted, double seen)
-{
- if (wanted == seen)
- printf("ok %d\n", n);
- else
- printf("not ok %d\n wanted: %g\n seen: %g\n", n, wanted, seen);
-}
-
-
-/*
- * Skip a test.
- */
-void
-skip(int n, const char *reason)
-{
- printf("ok %d # skip", n);
- if (reason != NULL)
- printf(" - %s", reason);
- putchar('\n');
-}
-
-
-/*
- * Report the same status on the next count tests.
- */
-void
-ok_block(int n, int count, int status)
-{
- int i;
-
- for (i = 0; i < count; i++)
- ok(n++, status);
-}
-
-
-/*
- * Skip the next count tests.
- */
-void
-skip_block(int n, int count, const char *reason)
-{
- int i;
-
- for (i = 0; i < count; i++)
- skip(n++, reason);
-}
-
-
-/*
- * An error handler that appends all errors to the errors global. Used by
- * error_capture.
- */
-static void
-message_log_buffer(int len, const char *fmt, va_list args, int error UNUSED)
-{
- char *message;
-
- message = xmalloc(len + 1);
- vsnprintf(message, len + 1, fmt, args);
- if (errors == NULL) {
- errors = concat(message, "\n", (char *) 0);
- } else {
- char *new_errors;
-
- new_errors = concat(errors, message, "\n", (char *) 0);
- free(errors);
- errors = new_errors;
- }
- free(message);
-}
-
-
-/*
- * Turn on the capturing of errors. Errors will be stored in the global
- * errors variable where they can be checked by the test suite. Capturing is
- * turned off with errors_uncapture.
- */
-void
-errors_capture(void)
-{
- if (errors != NULL) {
- free(errors);
- errors = NULL;
- }
- message_handlers_warn(1, message_log_buffer);
- message_handlers_notice(1, message_log_buffer);
-}
-
-
-/*
- * Turn off the capturing of errors again.
- */
-void
-errors_uncapture(void)
-{
- message_handlers_warn(1, message_log_stderr);
- message_handlers_notice(1, message_log_stdout);
-}
diff --git a/tests/libtest.h b/tests/libtest.h
deleted file mode 100644
index ac2b083..0000000
--- a/tests/libtest.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* $Id$
- *
- * Some utility routines for writing tests.
- *
- * Copyright 2006, 2007 Board of Trustees, Leland Stanford Jr. University
- * Copyright (c) 2004, 2005, 2006
- * by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- * 2002, 2003 by The Internet Software Consortium and Rich Salz
- *
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef LIBTEST_H
-#define LIBTEST_H 1
-
-#include <config.h>
-#include <portable/macros.h>
-
-/*
- * Used for iterating through arrays. ARRAY_SIZE returns the number of
- * elements in the array (useful for a < upper bound in a for loop) and
- * ARRAY_END returns a pointer to the element past the end (ISO C99 makes it
- * legal to refer to such a pointer as long as it's never dereferenced).
- */
-#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
-#define ARRAY_END(array) (&(array)[ARRAY_SIZE(array)])
-
-/* A global buffer into which errors_capture stores errors. */
-extern char *errors;
-
-BEGIN_DECLS
-
-void ok(int n, int success);
-void ok_int(int n, int wanted, int seen);
-void ok_double(int n, double wanted, double seen);
-void ok_string(int n, const char *wanted, const char *seen);
-void skip(int n, const char *reason);
-
-/* Report the same status on, or skip, the next count tests. */
-void ok_block(int n, int count, int success);
-void skip_block(int n, int count, const char *reason);
-
-/* Print out the number of tests and set standard output to line buffered. */
-void test_init(int count);
-
-/*
- * Turn on capturing of errors with errors_capture. Errors reported by warn
- * will be stored in the global errors variable. Turn this off again with
- * errors_uncapture. Caller is responsible for freeing errors when done.
- */
-void errors_capture(void);
-void errors_uncapture(void);
-
-END_DECLS
-
-#endif /* LIBTEST_H */
diff --git a/tests/libtest.sh b/tests/libtest.sh
deleted file mode 100644
index ed46d0e..0000000
--- a/tests/libtest.sh
+++ /dev/null
@@ -1,82 +0,0 @@
-# $Id$
-#
-# Shell function library for test cases.
-#
-# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University
-#
-# See LICENSE for licensing terms.
-
-# The count starts at 1 and is updated each time ok is printed. printcount
-# takes "ok" or "not ok".
-count=1
-printcount () {
- echo "$1 $count $2"
- count=`expr $count + 1`
-}
-
-# Run a program expected to succeed, and print ok if it does and produces
-# the correct output. Takes the output as the first argument, the command to
-# run as the second argument, and then all subsequent arguments are arguments
-# to the command.
-runsuccess () {
- w_output="$1"
- shift
- output=`"$@" 2>&1`
- status=$?
- if [ $status = 0 ] && [ x"$output" = x"$w_output" ] ; then
- printcount 'ok'
- else
- printcount 'not ok'
- echo " saw: $output"
- echo " not: $w_output"
- fi
-}
-
-# Run a program expected to fail and make sure it fails with the correct exit
-# status and the correct failure message. Takes the expected status, the
-# expected output, and then everything else is the command and arguments.
-# Strip the second colon and everything after it off the error message since
-# it's system-specific.
-runfailure () {
- w_status="$1"
- shift
- w_output="$1"
- shift
- output=`"$@" 2>&1`
- status=$?
- output=`echo "$output" | sed 's/\(:[^:]*\):.*/\1/'`
- if [ $status = $w_status ] && [ x"$output" = x"$w_output" ] ; then
- printcount 'ok'
- else
- printcount 'not ok'
- echo " saw: ($status) $output"
- echo " not: ($w_status) $w_output"
- fi
-}
-
-# Skip tests from $1 to $2 inclusive with reason $3.
-skip () {
- n="$1"
- while [ "$n" -le "$2" ] ; do
- echo ok "$n # skip $3"
- n=`expr "$n" + 1`
- done
-}
-
-# Given a file name or relative file path, try to cd to the correct directory
-# so that the relative file path is valid. Exits with an error if that isn't
-# possible.
-chdir_data () {
- if [ -f "../$1" ] ; then
- cd ..
- else
- if [ -f "tests/$1" ] ; then
- cd tests
- fi
- fi
- if [ ! -f "$1" ] ; then
- echo "Cannot locate $1" >&2
- exit 1
- fi
-}
diff --git a/tests/portable/asprintf-t.c b/tests/portable/asprintf-t.c
index d42e740..04fbd1b 100644
--- a/tests/portable/asprintf-t.c
+++ b/tests/portable/asprintf-t.c
@@ -1,9 +1,9 @@
-/* $Id$
- *
+/*
* asprintf and vasprintf test suite.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2006, 2008 Board of Trustees, Leland Stanford Jr. University
+ * Copyright 2006, 2008, 2009
+ * Board of Trustees, Leland Stanford Jr. University
*
* See LICENSE for licensing terms.
*/
@@ -11,9 +11,10 @@
#include <config.h>
#include <portable/system.h>
-#include <tests/libtest.h>
+#include <tests/tap/basic.h>
-int test_asprintf(char **, const char *, ...);
+int test_asprintf(char **, const char *, ...)
+ __attribute__((__format__(printf, 2, 3)));
int test_vasprintf(char **, const char *, va_list);
static int
@@ -33,25 +34,25 @@ main(void)
{
char *result = NULL;
- test_init(12);
+ plan(12);
- ok_int(1, 7, test_asprintf(&result, "%s", "testing"));
- ok_string(2, "testing", result);
+ is_int(7, test_asprintf(&result, "%s", "testing"), "asprintf length");
+ is_string("testing", result, "asprintf result");
free(result);
- ok(3, 1);
- ok_int(4, 0, test_asprintf(&result, "%s", ""));
- ok_string(5, "", result);
+ ok(3, "free asprintf");
+ is_int(0, test_asprintf(&result, "%s", ""), "asprintf empty length");
+ is_string("", result, "asprintf empty string");
free(result);
- ok(6, 1);
+ ok(6, "free asprintf of empty string");
- ok_int(7, 6, vatest(&result, "%d %s", 2, "test"));
- ok_string(8, "2 test", result);
+ is_int(6, vatest(&result, "%d %s", 2, "test"), "vasprintf length");
+ is_string("2 test", result, "vasprintf result");
free(result);
- ok(9, 1);
- ok_int(10, 0, vatest(&result, "%s", ""));
- ok_string(11, "", result);
+ ok(9, "free vasprintf");
+ is_int(0, vatest(&result, "%s", ""), "vasprintf empty length");
+ is_string("", result, "vasprintf empty string");
free(result);
- ok(12, 1);
+ ok(12, "free vasprintf of empty string");
return 0;
}
diff --git a/tests/portable/mkstemp-t.c b/tests/portable/mkstemp-t.c
new file mode 100644
index 0000000..54701f7
--- /dev/null
+++ b/tests/portable/mkstemp-t.c
@@ -0,0 +1,73 @@
+/*
+ * mkstemp test suite.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2002, 2004, 2008, 2009
+ * Board of Trustees, Leland Stanford Jr. University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <tests/tap/basic.h>
+
+int test_mkstemp(char *template);
+
+int
+main(void)
+{
+ int fd;
+ char template[] = "tsXXXXXXX";
+ char tooshort[] = "XXXXX";
+ char bad1[] = "/foo/barXXXXX";
+ char bad2[] = "/foo/barXXXXXX.out";
+ char buffer[256];
+ struct stat st1, st2;
+ ssize_t length;
+
+ plan(20);
+
+ /* First, test a few error messages. */
+ errno = 0;
+ is_int(-1, test_mkstemp(tooshort), "too short of template");
+ is_int(EINVAL, errno, "...with correct errno");
+ is_string("XXXXX", tooshort, "...and template didn't change");
+ errno = 0;
+ is_int(-1, test_mkstemp(bad1), "bad template");
+ is_int(EINVAL, errno, "...with correct errno");
+ is_string("/foo/barXXXXX", bad1, "...and template didn't change");
+ errno = 0;
+ is_int(-1, test_mkstemp(bad2), "template doesn't end in XXXXXX");
+ is_int(EINVAL, errno, "...with correct errno");
+ is_string("/foo/barXXXXXX.out", bad2, "...and template didn't change");
+ errno = 0;
+
+ /* Now try creating a real file. */
+ fd = test_mkstemp(template);
+ ok(fd >= 0, "mkstemp works with valid template");
+ ok(strcmp(template, "tsXXXXXXX") != 0, "...and template changed");
+ ok(strncmp(template, "tsX", 3) == 0, "...and didn't touch first X");
+ ok(access(template, F_OK) == 0, "...and the file exists");
+
+ /* Make sure that it's the same file as template refers to now. */
+ ok(stat(template, &st1) == 0, "...and stat of template works");
+ ok(fstat(fd, &st2) == 0, "...and stat of open file descriptor works");
+ ok(st1.st_ino == st2.st_ino, "...and they're the same file");
+ unlink(template);
+
+ /* Make sure the open mode is correct. */
+ length = strlen(template);
+ is_int(length, write(fd, template, length), "write to open file works");
+ ok(lseek(fd, 0, SEEK_SET) == 0, "...and rewind works");
+ is_int(length, read(fd, buffer, length), "...and the data is there");
+ buffer[length] = '\0';
+ is_string(template, buffer, "...and matches what we wrote");
+ close(fd);
+
+ return 0;
+}
diff --git a/tests/portable/mkstemp.c b/tests/portable/mkstemp.c
new file mode 100644
index 0000000..4632d3d
--- /dev/null
+++ b/tests/portable/mkstemp.c
@@ -0,0 +1,2 @@
+#define TESTING 1
+#include <portable/mkstemp.c>
diff --git a/tests/portable/setenv-t.c b/tests/portable/setenv-t.c
new file mode 100644
index 0000000..5bc59ce
--- /dev/null
+++ b/tests/portable/setenv-t.c
@@ -0,0 +1,46 @@
+/*
+ * setenv test suite.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2009 Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
+ * by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <errno.h>
+
+#include <tests/tap/basic.h>
+
+int test_setenv(const char *name, const char *value, int overwrite);
+
+static const char test_var[] = "SETENV_TEST";
+static const char test_value1[] = "Do not taunt Happy Fun Ball.";
+static const char test_value2[] = "Do not use Happy Fun Ball on concrete.";
+
+
+int
+main(void)
+{
+ plan(8);
+
+ if (getenv(test_var))
+ bail("%s already in the environment!", test_var);
+
+ ok(test_setenv(test_var, test_value1, 0) == 0, "set string 1");
+ is_string(test_value1, getenv(test_var), "...and getenv correct");
+ ok(test_setenv(test_var, test_value2, 0) == 0, "set string 2");
+ is_string(test_value1, getenv(test_var), "...and getenv unchanged");
+ ok(test_setenv(test_var, test_value2, 1) == 0, "overwrite string 2");
+ is_string(test_value2, getenv(test_var), "...and getenv changed");
+ ok(test_setenv(test_var, "", 1) == 0, "overwrite with empty string");
+ is_string("", getenv(test_var), "...and getenv correct");
+
+ return 0;
+}
diff --git a/tests/portable/setenv.c b/tests/portable/setenv.c
new file mode 100644
index 0000000..79a7efd
--- /dev/null
+++ b/tests/portable/setenv.c
@@ -0,0 +1,2 @@
+#define TESTING 1
+#include <portable/setenv.c>
diff --git a/tests/portable/snprintf-t.c b/tests/portable/snprintf-t.c
index c33e0e7..ca6ae61 100644
--- a/tests/portable/snprintf-t.c
+++ b/tests/portable/snprintf-t.c
@@ -1,33 +1,25 @@
-/* $Id$
- *
+/*
* snprintf test suite.
*
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2009 Board of Trustees, Leland Stanford Jr. University
* Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
* 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * See LICENSE for licensing terms.
*/
#include <config.h>
#include <portable/system.h>
-#include <tests/libtest.h>
+#include <tests/tap/basic.h>
+/*
+ * Intentionally don't add the printf attribute here since we pass a
+ * zero-length printf format during testing and don't want warnings.
+ */
int test_snprintf(char *str, size_t count, const char *fmt, ...);
int test_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
@@ -94,7 +86,7 @@ static unsigned long long ullong_nums[] = {
static void
-test_format(int n, int truncate, const char *expected, int count,
+test_format(bool truncate, const char *expected, int count,
const char *format, ...)
{
char buf[128];
@@ -104,16 +96,8 @@ test_format(int n, int truncate, const char *expected, int count,
va_start(args, format);
result = test_vsnprintf(buf, truncate ? 32 : sizeof(buf), format, args);
va_end(args);
- if (!strcmp(buf, expected) && result == count) {
- printf("ok %d\n", n);
- } else {
- printf("not ok %d\n", n);
- printf(" format: %s\n", format);
- if (strcmp(buf, expected))
- printf(" saw: %s\n want: %s\n", buf, expected);
- if (result != count)
- printf(" %d != %d\n", result, count);
- }
+ is_string(expected, buf, "format %s, wanted %s", format, expected);
+ is_int(count, result, "...and output length correct");
}
@@ -125,75 +109,69 @@ main(void)
long lcount;
char lgbuf[128];
- test_init((26 + (ARRAY_SIZE(fp_formats) - 1) * ARRAY_SIZE(fp_nums)
- + (ARRAY_SIZE(int_formats) - 1) * ARRAY_SIZE(int_nums)
- + (ARRAY_SIZE(uint_formats) - 1) * ARRAY_SIZE(uint_nums)
- + (ARRAY_SIZE(llong_formats) - 1) * ARRAY_SIZE(llong_nums)
- + (ARRAY_SIZE(ullong_formats) - 1) * ARRAY_SIZE(ullong_nums)));
-
- ok(1, test_snprintf(NULL, 0, "%s", "abcd") == 4);
- ok(2, test_snprintf(NULL, 0, "%d", 20) == 2);
- ok(3, test_snprintf(NULL, 0, "Test %.2s", "abcd") == 7);
- ok(4, test_snprintf(NULL, 0, "%c", 'a') == 1);
- ok(5, test_snprintf(NULL, 0, "") == 0);
-
- test_format(6, 1, "abcd", 4, "%s", "abcd");
- test_format(7, 1, "20", 2, "%d", 20);
- test_format(8, 1, "Test ab", 7, "Test %.2s", "abcd");
- test_format(9, 1, "a", 1, "%c", 'a');
- test_format(10, 1, "", 0, "");
- test_format(11, 1, "abcdefghijklmnopqrstuvwxyz01234", 36, "%s",
- string);
- test_format(12, 1, "abcdefghij", 10, "%.10s", string);
- test_format(13, 1, " abcdefghij", 12, "%12.10s", string);
- test_format(14, 1, " abcdefghijklmnopqrstuvwxyz0", 40, "%40s",
- string);
- test_format(15, 1, "abcdefghij ", 14, "%-14.10s", string);
- test_format(16, 1, " abcdefghijklmnopq", 50, "%50s",
- string);
- test_format(17, 1, "%abcd%", 6, "%%%0s%%", "abcd");
- test_format(18, 1, "", 0, "%.0s", string);
- test_format(19, 1, "abcdefghijklmnopqrstuvwxyz 444", 32, "%.26s %d",
+ plan(8 +
+ (18 + (ARRAY_SIZE(fp_formats) - 1) * ARRAY_SIZE(fp_nums)
+ + (ARRAY_SIZE(int_formats) - 1) * ARRAY_SIZE(int_nums)
+ + (ARRAY_SIZE(uint_formats) - 1) * ARRAY_SIZE(uint_nums)
+ + (ARRAY_SIZE(llong_formats) - 1) * ARRAY_SIZE(llong_nums)
+ + (ARRAY_SIZE(ullong_formats) - 1) * ARRAY_SIZE(ullong_nums)) * 2);
+
+ is_int(4, test_snprintf(NULL, 0, "%s", "abcd"), "simple string length");
+ is_int(2, test_snprintf(NULL, 0, "%d", 20), "number length");
+ is_int(7, test_snprintf(NULL, 0, "Test %.2s", "abcd"), "limited string");
+ is_int(1, test_snprintf(NULL, 0, "%c", 'a'), "character length");
+ is_int(0, test_snprintf(NULL, 0, ""), "empty format length");
+
+ test_format(true, "abcd", 4, "%s", "abcd");
+ test_format(true, "20", 2, "%d", 20);
+ test_format(true, "Test ab", 7, "Test %.2s", "abcd");
+ test_format(true, "a", 1, "%c", 'a');
+ test_format(true, "", 0, "");
+ test_format(true, "abcdefghijklmnopqrstuvwxyz01234", 36, "%s", string);
+ test_format(true, "abcdefghij", 10, "%.10s", string);
+ test_format(true, " abcdefghij", 12, "%12.10s", string);
+ test_format(true, " abcdefghijklmnopqrstuvwxyz0", 40, "%40s", string);
+ test_format(true, "abcdefghij ", 14, "%-14.10s", string);
+ test_format(true, " abcdefghijklmnopq", 50, "%50s", string);
+ test_format(true, "%abcd%", 6, "%%%0s%%", "abcd");
+ test_format(true, "", 0, "%.0s", string);
+ test_format(true, "abcdefghijklmnopqrstuvwxyz 444", 32, "%.26s %d",
string, 4444);
- test_format(20, 1, "abcdefghijklmnopqrstuvwxyz -2.", 32,
- "%.26s %.1f", string, -2.5);
- test_format(21, 1, "abcdefghij4444", 14, "%.10s%n%d", string, &count,
- 4444);
- ok(22, count == 10);
- test_format(23, 1, "abcdefghijklmnopqrstuvwxyz01234", 36, "%n%s%ln",
+ test_format(true, "abcdefghijklmnopqrstuvwxyz -2.", 32, "%.26s %.1f",
+ string, -2.5);
+ test_format(true, "abcdefghij4444", 14, "%.10s%n%d", string, &count, 4444);
+ is_int(10, count, "correct output from %%n");
+ test_format(true, "abcdefghijklmnopqrstuvwxyz01234", 36, "%n%s%ln",
&count, string, &lcount);
- ok(24, count == 0);
- ok(25, lcount == 31);
- test_format(26, 1, "(null)", 6, "%s", NULL);
+ is_int(0, count, "correct output from two %%n");
+ is_int(31, lcount, "correct output from long %%ln");
+ test_format(true, "(null)", 6, "%s", NULL);
n = 26;
for (i = 0; fp_formats[i] != NULL; i++)
for (j = 0; j < ARRAY_SIZE(fp_nums); j++) {
count = sprintf(lgbuf, fp_formats[i], fp_nums[j]);
- test_format(++n, 0, lgbuf, count, fp_formats[i], fp_nums[j]);
+ test_format(false, lgbuf, count, fp_formats[i], fp_nums[j]);
}
for (i = 0; int_formats[i] != NULL; i++)
for (j = 0; j < ARRAY_SIZE(int_nums); j++) {
count = sprintf(lgbuf, int_formats[i], int_nums[j]);
- test_format(++n, 0, lgbuf, count, int_formats[i],
- int_nums[j]);
+ test_format(false, lgbuf, count, int_formats[i], int_nums[j]);
}
for (i = 0; uint_formats[i] != NULL; i++)
for (j = 0; j < ARRAY_SIZE(uint_nums); j++) {
count = sprintf(lgbuf, uint_formats[i], uint_nums[j]);
- test_format(++n, 0, lgbuf, count, uint_formats[i],
- uint_nums[j]);
+ test_format(false, lgbuf, count, uint_formats[i], uint_nums[j]);
}
for (i = 0; llong_formats[i] != NULL; i++)
for (j = 0; j < ARRAY_SIZE(llong_nums); j++) {
count = sprintf(lgbuf, llong_formats[i], llong_nums[j]);
- test_format(++n, 0, lgbuf, count, llong_formats[i],
- llong_nums[j]);
+ test_format(false, lgbuf, count, llong_formats[i], llong_nums[j]);
}
for (i = 0; ullong_formats[i] != NULL; i++)
for (j = 0; j < ARRAY_SIZE(ullong_nums); j++) {
count = sprintf(lgbuf, ullong_formats[i], ullong_nums[j]);
- test_format(++n, 0, lgbuf, count, ullong_formats[i],
+ test_format(false, lgbuf, count, ullong_formats[i],
ullong_nums[j]);
}
diff --git a/tests/portable/strlcat-t.c b/tests/portable/strlcat-t.c
index c860803..e02c277 100644
--- a/tests/portable/strlcat-t.c
+++ b/tests/portable/strlcat-t.c
@@ -1,32 +1,20 @@
-/* $Id$
- *
+/*
* strlcat test suite.
*
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2009 Board of Trustees, Leland Stanford Jr. University
* Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
* 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * See LICENSE for licensing terms.
*/
#include <config.h>
#include <portable/system.h>
-#include <tests/libtest.h>
+#include <tests/tap/basic.h>
size_t test_strlcat(char *, const char *, size_t);
@@ -36,42 +24,51 @@ main(void)
{
char buffer[10] = "";
- test_init(27);
+ plan(27);
- ok_int(1, 3, test_strlcat(buffer, "foo", sizeof(buffer)));
- ok_string(2, "foo", buffer);
- ok_int(3, 7, test_strlcat(buffer, " bar", sizeof(buffer)));
- ok_string(4, "foo bar", buffer);
- ok_int(5, 9, test_strlcat(buffer, "!!", sizeof(buffer)));
- ok_string(6, "foo bar!!", buffer);
- ok_int(7, 10, test_strlcat(buffer, "!", sizeof(buffer)));
- ok_string(8, "foo bar!!", buffer);
- ok(9, buffer[9] == '\0');
+ is_int(3, test_strlcat(buffer, "foo", sizeof(buffer)),
+ "strlcat into empty buffer");
+ is_string("foo", buffer, "...with right output");
+ is_int(7, test_strlcat(buffer, " bar", sizeof(buffer)),
+ "...and append more");
+ is_string("foo bar", buffer, "...and output is still correct");
+ is_int(9, test_strlcat(buffer, "!!", sizeof(buffer)),
+ "...and append to buffer limit");
+ is_string("foo bar!!", buffer, "...output is still correct");
+ is_int(10, test_strlcat(buffer, "!", sizeof(buffer)),
+ "...append one more character");
+ is_string("foo bar!!", buffer, "...and output didn't change");
+ ok(buffer[9] == '\0', "...buffer still nul-terminated");
buffer[0] = '\0';
- ok_int(10, 11, test_strlcat(buffer, "hello world", sizeof(buffer)));
- ok_string(11, "hello wor", buffer);
- ok(12, buffer[9] == '\0');
+ is_int(11, test_strlcat(buffer, "hello world", sizeof(buffer)),
+ "append single long string");
+ is_string("hello wor", buffer, "...string truncates properly");
+ ok(buffer[9] == '\0', "...buffer still nul-terminated");
buffer[0] = '\0';
- ok_int(13, 7, test_strlcat(buffer, "sausage", 5));
- ok_string(14, "saus", buffer);
- ok_int(15, 14, test_strlcat(buffer, "bacon eggs", sizeof(buffer)));
- ok_string(16, "sausbacon", buffer);
+ is_int(7, test_strlcat(buffer, "sausage", 5), "lie about buffer length");
+ is_string("saus", buffer, "...contents are correct");
+ is_int(14, test_strlcat(buffer, "bacon eggs", sizeof(buffer)),
+ "...add more up to real size");
+ is_string("sausbacon", buffer, "...and result is correct");
/* Make sure that with a size of 0, the destination isn't changed. */
- ok_int(17, 11, test_strlcat(buffer, "!!", 0));
- ok_string(18, "sausbacon", buffer);
+ is_int(11, test_strlcat(buffer, "!!", 0), "no change with size of 0");
+ is_string("sausbacon", buffer, "...and content is the same");
/* Now play with empty strings. */
- ok_int(19, 9, test_strlcat(buffer, "", 0));
- ok_string(20, "sausbacon", buffer);
+ is_int(9, test_strlcat(buffer, "", 0),
+ "correct count when appending empty string");
+ is_string("sausbacon", buffer, "...and contents are unchanged");
buffer[0] = '\0';
- ok_int(21, 0, test_strlcat(buffer, "", sizeof(buffer)));
- ok_string(22, "", buffer);
- ok_int(23, 3, test_strlcat(buffer, "foo", 2));
- ok_string(24, "f", buffer);
- ok(25, buffer[1] == '\0');
- ok_int(26, 1, test_strlcat(buffer, "", sizeof(buffer)));
- ok(27, buffer[1] == '\0');
+ is_int(0, test_strlcat(buffer, "", sizeof(buffer)),
+ "correct count when appending empty string to empty buffer");
+ is_string("", buffer, "...and buffer content is correct");
+ is_int(3, test_strlcat(buffer, "foo", 2), "append to length 2 buffer");
+ is_string("f", buffer, "...and got only a single character");
+ ok(buffer[1] == '\0', "...and buffer is still nul-terminated");
+ is_int(1, test_strlcat(buffer, "", sizeof(buffer)),
+ "append an empty string");
+ ok(buffer[1] == '\0', "...and buffer is still nul-terminated");
return 0;
}
diff --git a/tests/portable/strlcpy-t.c b/tests/portable/strlcpy-t.c
index 8fb1f9c..ba224ba 100644
--- a/tests/portable/strlcpy-t.c
+++ b/tests/portable/strlcpy-t.c
@@ -1,32 +1,20 @@
-/* $Id$
- *
+/*
* strlcpy test suite.
*
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2009 Board of Trustees, Leland Stanford Jr. University
* Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
* 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * See LICENSE for licensing terms.
*/
#include <config.h>
#include <portable/system.h>
-#include <tests/libtest.h>
+#include <tests/tap/basic.h>
size_t test_strlcpy(char *, const char *, size_t);
@@ -36,37 +24,43 @@ main(void)
{
char buffer[10];
- test_init(23);
+ plan(23);
- ok_int(1, 3, test_strlcpy(buffer, "foo", sizeof(buffer)));
- ok_string(2, "foo", buffer);
- ok_int(3, 9, test_strlcpy(buffer, "hello wor", sizeof(buffer)));
- ok_string(4, "hello wor", buffer);
- ok_int(5, 10, test_strlcpy(buffer, "world hell", sizeof(buffer)));
- ok_string(6, "world hel", buffer);
- ok(7, buffer[9] == '\0');
- ok_int(8, 11, test_strlcpy(buffer, "hello world", sizeof(buffer)));
- ok_string(9, "hello wor", buffer);
- ok(10, buffer[9] == '\0');
+ is_int(3, test_strlcpy(buffer, "foo", sizeof(buffer)), "simple strlcpy");
+ is_string("foo", buffer, "...result is correct");
+ is_int(9, test_strlcpy(buffer, "hello wor", sizeof(buffer)),
+ "strlcpy exact length of buffer");
+ is_string("hello wor", buffer, "...result is correct");
+ is_int(10, test_strlcpy(buffer, "world hell", sizeof(buffer)),
+ "strlcpy one more than buffer length");
+ is_string("world hel", buffer, "...result is correct");
+ ok(buffer[9] == '\0', "...buffer is nul-terminated");
+ is_int(11, test_strlcpy(buffer, "hello world", sizeof(buffer)),
+ "strlcpy more than buffer length");
+ is_string("hello wor", buffer, "...result is correct");
+ ok(buffer[9] == '\0', "...buffer is nul-terminated");
/* Make sure that with a size of 0, the destination isn't changed. */
- ok_int(11, 3, test_strlcpy(buffer, "foo", 0));
- ok_string(12, "hello wor", buffer);
+ is_int(3, test_strlcpy(buffer, "foo", 0), "buffer unchanged if size 0");
+ is_string("hello wor", buffer, "...contents still the same");
/* Now play with empty strings. */
- ok_int(13, 0, test_strlcpy(buffer, "", 0));
- ok_string(14, "hello wor", buffer);
- ok_int(15, 0, test_strlcpy(buffer, "", sizeof(buffer)));
- ok_string(16, "", buffer);
- ok_int(17, 3, test_strlcpy(buffer, "foo", 2));
- ok_string(18, "f", buffer);
- ok(19, buffer[1] == '\0');
- ok_int(20, 0, test_strlcpy(buffer, "", 1));
- ok(21, buffer[0] == '\0');
+ is_int(0, test_strlcpy(buffer, "", 0), "copy empty string with size 0");
+ is_string("hello wor", buffer, "...buffer unchanged");
+ is_int(0, test_strlcpy(buffer, "", sizeof(buffer)),
+ "copy empty string into full buffer");
+ is_string("", buffer, "...buffer now empty string");
+ is_int(3, test_strlcpy(buffer, "foo", 2),
+ "copy string into buffer of size 2");
+ is_string("f", buffer, "...got one character");
+ ok(buffer[1] == '\0', "...buffer is nul-terminated");
+ is_int(0, test_strlcpy(buffer, "", 1),
+ "copy empty string into buffer of size 1");
+ ok(buffer[0] == '\0', "...buffer is empty string");
/* Finally, check using strlcpy as strlen. */
- ok_int(22, 3, test_strlcpy(NULL, "foo", 0));
- ok_int(23, 11, test_strlcpy(NULL, "hello world", 0));
+ is_int(3, test_strlcpy(NULL, "foo", 0), "use strlcpy as strlen");
+ is_int(11, test_strlcpy(NULL, "hello world", 0), "...again");
return 0;
}
diff --git a/tests/runtests.c b/tests/runtests.c
index abad3b6..1670012 100644
--- a/tests/runtests.c
+++ b/tests/runtests.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Run a set of tests, reporting results.
*
* Usage:
@@ -18,12 +17,13 @@
*
* where <number> is the number of the test. ok indicates success, not ok
* indicates failure, and "# skip" indicates the test was skipped for some
- * reason (maybe because it doesn't apply to this platform).
+ * reason (maybe because it doesn't apply to this platform). This is a subset
+ * of TAP as documented in Test::Harness::TAP, which comes with Perl.
*
* Any bug reports, bug fixes, and improvements are very much welcome and
* should be sent to the e-mail address below.
*
- * Copyright 2000, 2001, 2004, 2006, 2007, 2008
+ * Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009
* Russ Allbery <rra@stanford.edu>
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -45,16 +45,19 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include <config.h>
-#include <portable/system.h>
-
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
+#include <unistd.h>
/* sys/time.h must be included before sys/resource.h on some platforms. */
#include <sys/resource.h>
@@ -64,6 +67,19 @@
# define WCOREDUMP(status) ((unsigned)(status) & 0x80)
#endif
+/*
+ * The source and build versions of the tests directory. This is used to set
+ * the SOURCE and BUILD environment variables and find test programs, if set.
+ * Normally, this should be set as part of the build process to the test
+ * subdirectories of $(abs_top_srcdir) and $(abs_top_builddir) respectively.
+ */
+#ifndef SOURCE
+# define SOURCE NULL
+#endif
+#ifndef BUILD
+# define BUILD NULL
+#endif
+
/* Test status codes. */
enum test_status {
TEST_FAIL,
@@ -79,7 +95,8 @@ enum test_status {
/* Structure to hold data for a set of tests. */
struct testset {
- const char *file; /* The file name of the test. */
+ char *file; /* The file name of the test. */
+ char *path; /* The path to the test program. */
int count; /* Expected count of tests. */
int current; /* The last seen test number. */
int length; /* The length of the last status message. */
@@ -90,6 +107,8 @@ struct testset {
int aborted; /* Whether the set as aborted. */
int reported; /* Whether the results were reported. */
int status; /* The exit status of the test. */
+ int all_skipped; /* Whether all tests were skipped. */
+ char *reason; /* Why all tests were skipped. */
};
/* Structure to hold a linked list of test sets. */
@@ -104,8 +123,7 @@ struct testlist {
*/
static const char banner[] = "\n\
Running all tests listed in %s. If any tests fail, run the failing\n\
-test program by hand to see more details. The test program will have the\n\
-same name as the test set but with \"-t\" appended.\n\n";
+test program with runtests -o to see more details.\n\n";
/* Header for reports of failed tests. */
static const char header[] = "\n\
@@ -116,22 +134,6 @@ Failed Set Fail/Total (%) Skip Stat Failing Tests\n\
#define xmalloc(size) x_malloc((size), __FILE__, __LINE__)
#define xstrdup(p) x_strdup((p), __FILE__, __LINE__)
-/* Internal prototypes. */
-static void sysdie(const char *format, ...);
-static void *x_malloc(size_t, const char *file, int line);
-static char *x_strdup(const char *, const char *file, int line);
-static int test_analyze(struct testset *);
-static int test_batch(const char *testlist);
-static void test_checkline(const char *line, struct testset *);
-static void test_fail_summary(const struct testlist *);
-static int test_init(const char *line, struct testset *);
-static int test_print_range(int first, int last, int chars, int limit);
-static void test_summarize(struct testset *, int status);
-static pid_t test_start(const char *path, int *fd);
-static double tv_diff(const struct timeval *, const struct timeval *);
-static double tv_seconds(const struct timeval *);
-static double tv_sum(const struct timeval *, const struct timeval *);
-
/*
* Report a fatal error, including the results of strerror, and exit.
@@ -220,6 +222,19 @@ tv_sum(const struct timeval *tv1, const struct timeval *tv2)
/*
+ * Given a pointer to a string, skip any leading whitespace and return a
+ * pointer to the first non-whitespace character.
+ */
+static const char *
+skip_whitespace(const char *p)
+{
+ while (isspace((unsigned char)(*p)))
+ p++;
+ return p;
+}
+
+
+/*
* Read the first line of test output, which should contain the range of
* test numbers, and initialize the testset structure. Assume it was zeroed
* before being passed in. Return true if initialization succeeds, false
@@ -235,15 +250,34 @@ test_init(const char *line, struct testset *ts)
* such as 1..10, accept that too for compatibility with Perl's
* Test::Harness.
*/
- while (isspace((unsigned char)(*line)))
- line++;
+ line = skip_whitespace(line);
if (strncmp(line, "1..", 3) == 0)
line += 3;
- /* Get the count, check it for validity, and initialize the struct. */
- i = atoi(line);
+ /*
+ * Get the count, check it for validity, and initialize the struct. If we
+ * have something of the form "1..0 # skip foo", the whole file was
+ * skipped; record that.
+ */
+ i = strtol(line, (char **) &line, 10);
+ if (i == 0) {
+ line = skip_whitespace(line);
+ if (*line == '#') {
+ line = skip_whitespace(line + 1);
+ if (strncasecmp(line, "skip", 4) == 0) {
+ line = skip_whitespace(line + 4);
+ if (*line != '\0') {
+ ts->reason = xstrdup(line);
+ ts->reason[strlen(ts->reason) - 1] = '\0';
+ }
+ ts->all_skipped = 1;
+ ts->aborted = 1;
+ return 0;
+ }
+ }
+ }
if (i <= 0) {
- puts("invalid test count");
+ puts("ABORTED (invalid test count)");
ts->aborted = 1;
ts->reported = 1;
return 0;
@@ -330,8 +364,28 @@ static void
test_checkline(const char *line, struct testset *ts)
{
enum test_status status = TEST_PASS;
+ const char *bail;
+ char *end;
int current;
+ /* Before anything, check for a test abort. */
+ bail = strstr(line, "Bail out!");
+ if (bail != NULL) {
+ bail = skip_whitespace(bail + strlen("Bail out!"));
+ if (*bail != '\0') {
+ int length;
+
+ length = strlen(bail);
+ if (bail[length - 1] == '\n')
+ length--;
+ test_backspace(ts);
+ printf("ABORTED (%.*s)\n", length, bail);
+ ts->reported = 1;
+ }
+ ts->aborted = 1;
+ return;
+ }
+
/*
* If the given line isn't newline-terminated, it was too big for an
* fgets(), which means ignore it.
@@ -344,37 +398,40 @@ test_checkline(const char *line, struct testset *ts)
status = TEST_FAIL;
line += 4;
}
- if (strncmp(line, "ok ", 3) != 0)
- return;
- line += 3;
- current = atoi(line);
- if (current == 0)
+ if (strncmp(line, "ok", 2) != 0)
return;
- if (current < 0 || current > ts->count) {
+ line = skip_whitespace(line + 2);
+ errno = 0;
+ current = strtol(line, &end, 10);
+ if (errno != 0 || end == line)
+ current = ts->current + 1;
+ if (current <= 0 || current > ts->count) {
test_backspace(ts);
- printf("invalid test number %d\n", current);
+ printf("ABORTED (invalid test number %d)\n", current);
ts->aborted = 1;
ts->reported = 1;
return;
}
- while (isspace((unsigned char)(*line)))
- line++;
+
+ /*
+ * Handle directives. We should probably do something more interesting
+ * with unexpected passes of todo tests.
+ */
while (isdigit((unsigned char)(*line)))
line++;
- while (isspace((unsigned char)(*line)))
- line++;
+ line = skip_whitespace(line);
if (*line == '#') {
- line++;
- while (isspace((unsigned char)(*line)))
- line++;
- if (strncmp(line, "skip", 4) == 0)
+ line = skip_whitespace(line + 1);
+ if (strncasecmp(line, "skip", 4) == 0)
status = TEST_SKIP;
+ if (strncasecmp(line, "todo", 4) == 0)
+ status = (status == TEST_FAIL) ? TEST_SKIP : TEST_FAIL;
}
/* Make sure that the test number is in range and not a duplicate. */
if (ts->results[current - 1] != TEST_INVALID) {
test_backspace(ts);
- printf("duplicate test number %d\n", current);
+ printf("ABORTED (duplicate test number %d)\n", current);
ts->aborted = 1;
ts->reported = 1;
return;
@@ -450,9 +507,9 @@ test_summarize(struct testset *ts, int status)
int last = 0;
if (ts->aborted) {
- fputs("aborted", stdout);
+ fputs("ABORTED", stdout);
if (ts->count > 0)
- printf(", passed %d/%d", ts->passed, ts->count - ts->skipped);
+ printf(" (passed %d/%d)", ts->passed, ts->count - ts->skipped);
} else {
for (i = 0; i < ts->count; i++) {
if (ts->results[i] == TEST_INVALID) {
@@ -521,19 +578,25 @@ test_analyze(struct testset *ts)
{
if (ts->reported)
return 0;
- if (WIFEXITED(ts->status) && WEXITSTATUS(ts->status) != 0) {
+ if (ts->all_skipped) {
+ if (ts->reason == NULL)
+ puts("skipped");
+ else
+ printf("skipped (%s)\n", ts->reason);
+ return 1;
+ } else if (WIFEXITED(ts->status) && WEXITSTATUS(ts->status) != 0) {
switch (WEXITSTATUS(ts->status)) {
case CHILDERR_DUP:
if (!ts->reported)
- puts("can't dup file descriptors");
+ puts("ABORTED (can't dup file descriptors)");
break;
case CHILDERR_EXEC:
if (!ts->reported)
- puts("execution failed (not found?)");
+ puts("ABORTED (execution failed -- not found?)");
break;
case CHILDERR_STDERR:
if (!ts->reported)
- puts("can't open /dev/null");
+ puts("ABORTED (can't open /dev/null)");
break;
default:
test_summarize(ts, WEXITSTATUS(ts->status));
@@ -562,17 +625,12 @@ test_run(struct testset *ts)
int outfd, i, status;
FILE *output;
char buffer[BUFSIZ];
- char *file;
/*
* Initialize the test and our data structures, flagging this set in error
* if the initialization fails.
*/
- file = xmalloc(strlen(ts->file) + 3);
- strcpy(file, ts->file);
- strcat(file, "-t");
- testpid = test_start(file, &outfd);
- free(file);
+ testpid = test_start(ts->path, &outfd);
output = fdopen(outfd, "r");
if (!output) {
puts("ABORTED");
@@ -581,11 +639,8 @@ test_run(struct testset *ts)
}
if (!fgets(buffer, sizeof(buffer), output))
ts->aborted = 1;
- if (!ts->aborted && !test_init(buffer, ts)) {
- while (fgets(buffer, sizeof(buffer), output))
- ;
+ if (!ts->aborted && !test_init(buffer, ts))
ts->aborted = 1;
- }
/* Pass each line of output to test_checkline(). */
while (!ts->aborted && fgets(buffer, sizeof(buffer), output))
@@ -595,16 +650,23 @@ test_run(struct testset *ts)
test_backspace(ts);
/*
- * Close the output descriptor, retrieve the exit status, and pass that
- * information to test_analyze() for eventual output.
+ * Consume the rest of the test output, close the output descriptor,
+ * retrieve the exit status, and pass that information to test_analyze()
+ * for eventual output.
*/
+ while (fgets(buffer, sizeof(buffer), output))
+ ;
fclose(output);
child = waitpid(testpid, &ts->status, 0);
if (child == (pid_t) -1) {
- puts("ABORTED");
- fflush(stdout);
+ if (!ts->reported) {
+ puts("ABORTED");
+ fflush(stdout);
+ }
sysdie("waitpid for %u failed", (unsigned int) testpid);
}
+ if (ts->all_skipped)
+ ts->aborted = 0;
status = test_analyze(ts);
/* Convert missing tests to failed tests. */
@@ -667,12 +729,53 @@ test_fail_summary(const struct testlist *fails)
/*
+ * Given the name of a test, a pointer to the testset struct, and the source
+ * and build directories, find the test. We try first relative to the current
+ * directory, then in the build directory (if not NULL), then in the source
+ * directory. In each of those directories, we first try a "-t" extension and
+ * then a ".t" extension. When we find an executable program, we fill in the
+ * path member of the testset struct. If none of those paths are executable,
+ * just fill in the name of the test with "-t" appended.
+ *
+ * The caller is responsible for freeing the path member of the testset
+ * struct.
+ */
+static void
+find_test(const char *name, struct testset *ts, const char *source,
+ const char *build)
+{
+ char *path;
+ const char *bases[] = { ".", build, source, NULL };
+ int i;
+
+ for (i = 0; bases[i] != NULL; i++) {
+ path = xmalloc(strlen(bases[i]) + strlen(name) + 4);
+ sprintf(path, "%s/%s-t", bases[i], name);
+ if (access(path, X_OK) != 0)
+ path[strlen(path) - 2] = '.';
+ if (access(path, X_OK) == 0)
+ break;
+ free(path);
+ path = NULL;
+ }
+ if (path == NULL) {
+ path = xmalloc(strlen(name) + 3);
+ sprintf(path, "%s-t", name);
+ }
+ ts->path = path;
+}
+
+
+/*
* Run a batch of tests from a given file listing each test on a line by
- * itself. The file must be rewindable. Returns true iff all tests
+ * itself. Takes two additional parameters: the root of the source directory
+ * and the root of the build directory. Test programs will be first searched
+ * for in the current directory, then the build directory, then the source
+ * directory. The file must be rewindable. Returns true iff all tests
* passed.
*/
static int
-test_batch(const char *testlist)
+test_batch(const char *testlist, const char *source, const char *build)
{
FILE *tests;
size_t length, i;
@@ -742,7 +845,14 @@ test_batch(const char *testlist)
fflush(stdout);
memset(&ts, 0, sizeof(ts));
ts.file = xstrdup(buffer);
- if (!test_run(&ts)) {
+ find_test(buffer, &ts, source, build);
+ ts.reason = NULL;
+ if (test_run(&ts)) {
+ free(ts.file);
+ free(ts.path);
+ if (ts.reason != NULL)
+ free(ts.reason);
+ } else {
tmp = xmalloc(sizeof(struct testset));
memcpy(tmp, &ts, sizeof(struct testset));
if (!failhead) {
@@ -758,9 +868,9 @@ test_batch(const char *testlist)
}
}
aborted += ts.aborted;
- total += ts.count;
+ total += ts.count + ts.all_skipped;
passed += ts.passed;
- skipped += ts.skipped;
+ skipped += ts.skipped + ts.all_skipped;
failed += ts.failed;
}
total -= skipped;
@@ -770,7 +880,8 @@ test_batch(const char *testlist)
getrusage(RUSAGE_CHILDREN, &stats);
/* Print out our final results. */
- if (failhead) test_fail_summary(failhead);
+ if (failhead)
+ test_fail_summary(failhead);
putchar('\n');
if (aborted != 0) {
if (aborted == 1)
@@ -801,15 +912,80 @@ test_batch(const char *testlist)
/*
- * Main routine. Given a file listing tests, run each test listed.
+ * Run a single test case. This involves just running the test program after
+ * having done the environment setup and finding the test program.
+ */
+static void
+test_single(const char *program, const char *source, const char *build)
+{
+ struct testset ts;
+
+ memset(&ts, 0, sizeof(ts));
+ find_test(program, &ts, source, build);
+ if (execl(ts.path, ts.path, (char *) 0) == -1)
+ sysdie("cannot exec %s", ts.path);
+}
+
+
+/*
+ * Main routine. Set the SOURCE and BUILD environment variables and then,
+ * given a file listing tests, run each test listed.
*/
int
main(int argc, char *argv[])
{
- if (argc != 2) {
+ int option;
+ int single = 0;
+ char *setting;
+ const char *list;
+ const char *source = SOURCE;
+ const char *build = BUILD;
+
+ while ((option = getopt(argc, argv, "b:os:")) != EOF) {
+ switch (option) {
+ case 'b':
+ build = optarg;
+ break;
+ case 'o':
+ single = 1;
+ break;
+ case 's':
+ source = optarg;
+ break;
+ default:
+ exit(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc != 1) {
fprintf(stderr, "Usage: runtests <test-list>\n");
exit(1);
}
- printf(banner, argv[1]);
- exit(test_batch(argv[1]) ? 0 : 1);
+
+ if (source != NULL) {
+ setting = xmalloc(strlen("SOURCE=") + strlen(source) + 1);
+ sprintf(setting, "SOURCE=%s", source);
+ if (putenv(setting) != 0)
+ sysdie("cannot set SOURCE in the environment");
+ }
+ if (build != NULL) {
+ setting = xmalloc(strlen("BUILD=") + strlen(build) + 1);
+ sprintf(setting, "BUILD=%s", build);
+ if (putenv(setting) != 0)
+ sysdie("cannot set BUILD in the environment");
+ }
+
+ if (single) {
+ test_single(argv[0], source, build);
+ exit(0);
+ } else {
+ list = strrchr(argv[0], '/');
+ if (list == NULL)
+ list = argv[0];
+ else
+ list++;
+ printf(banner, list);
+ exit(test_batch(argv[0], source, build) ? 0 : 1);
+ }
}
diff --git a/tests/server/admin-t.in b/tests/server/admin-t
index be40880..5bde104 100644..100755
--- a/tests/server/admin-t.in
+++ b/tests/server/admin-t
@@ -1,23 +1,21 @@
#!/usr/bin/perl -w
-# $Id$
#
# Tests for the wallet-admin dispatch code.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
use strict;
-use Test::More tests => 54;
+use Test::More tests => 36;
# Create a dummy class for Wallet::Admin that prints what method was called
# with its arguments and returns data for testing.
package Wallet::Admin;
-use vars qw($empty $error);
+use vars qw($error);
$error = 0;
-$empty = 0;
sub error {
if ($error) {
@@ -45,19 +43,6 @@ sub initialize {
return 1;
}
-sub list_objects {
- print "list_objects\n";
- return if ($error or $empty);
- return ([ keytab => 'host/windlord.stanford.edu' ],
- [ file => 'unix-wallet-password' ]);
-}
-
-sub list_acls {
- print "list_acls\n";
- return if ($error or $empty);
- return ([ 1, 'ADMIN' ], [ 2, 'group/admins' ], [ 4, 'group/users' ]);
-}
-
sub register_object {
shift;
print "register_object @_\n";
@@ -76,7 +61,7 @@ sub register_verifier {
# Wallet::Admin package has already been loaded.
package main;
$INC{'Wallet/Admin.pm'} = 'FAKE';
-eval { do '@abs_top_srcdir@/server/wallet-admin' };
+eval { do "$ENV{SOURCE}/../server/wallet-admin" };
# Run the wallet admin client. This fun hack takes advantage of the fact that
# the wallet admin client is written in Perl so that we can substitute our own
@@ -99,10 +84,9 @@ is ($err, "unknown command foo\n", 'Unknown command');
is ($out, "new\n", ' and nothing ran');
# Check too few and too many arguments for every command.
-my %commands = (destroy => [0, 0],
- initialize => [1, 1],
- list => [1, 1],
- register => [3, 3]);
+my %commands = (destroy => [0, 0],
+ initialize => [1, 1],
+ register => [3, 3]);
for my $command (sort keys %commands) {
my ($min, $max) = @{ $commands{$command} };
if ($min > 0) {
@@ -111,10 +95,12 @@ for my $command (sort keys %commands) {
"Too few arguments for $command");
is ($out, "new\n", ' and nothing ran');
}
- ($out, $err) = run_admin ($command, ('foo') x ($max + 1));
- is ($err, "too many arguments to $command\n",
- "Too many arguments for $command");
- is ($out, "new\n", ' and nothing ran');
+ if ($max >= 0) {
+ ($out, $err) = run_admin ($command, ('foo') x ($max + 1));
+ is ($err, "too many arguments to $command\n",
+ "Too many arguments for $command");
+ is ($out, "new\n", ' and nothing ran');
+ }
}
# Test destroy.
@@ -150,22 +136,6 @@ is ($out, "new\n", ' and nothing was run');
is ($err, '', 'Initialize succeeds with a principal');
is ($out, "new\ninitialize rra\@stanford.edu\n", ' and runs the right code');
-# Test list.
-($out, $err) = run_admin ('list', 'foo');
-is ($err, "only objects or acls are supported for list\n",
- 'List requires a known object');
-is ($out, "new\n", ' and nothing was run');
-($out, $err) = run_admin ('list', 'objects');
-is ($err, '', 'List succeeds for objects');
-is ($out, "new\nlist_objects\n"
- . "keytab host/windlord.stanford.edu\nfile unix-wallet-password\n",
- ' and returns the right output');
-($out, $err) = run_admin ('list', 'acls');
-is ($err, '', 'List succeeds for ACLs');
-is ($out, "new\nlist_acls\n"
- . "ADMIN (ACL ID: 1)\ngroup/admins (ACL ID: 2)\ngroup/users (ACL ID: 4)\n",
- ' and returns the right output');
-
# Test register.
($out, $err) = run_admin ('register', 'foo', 'foo', 'Foo::Bar');
is ($err, "only object or verifier is supported for register\n",
@@ -191,12 +161,6 @@ is ($out, "new\n"
is ($err, "some error\n", 'Error handling succeeds for initialize');
is ($out, "new\ninitialize rra\@stanford.edu\n",
' and calls the right methods');
-($out, $err) = run_admin ('list', 'objects');
-is ($err, "some error\n", 'Error handling succeeds for list objects');
-is ($out, "new\nlist_objects\n", ' and calls the right methods');
-($out, $err) = run_admin ('list', 'acls');
-is ($err, "some error\n", 'Error handling succeeds for list acls');
-is ($out, "new\nlist_acls\n", ' and calls the right methods');
($out, $err) = run_admin ('register', 'object', 'foo', 'Foo::Object');
is ($err, "some error\n", 'Error handling succeeds for register object');
is ($out, "new\nregister_object foo Foo::Object\n",
@@ -205,13 +169,3 @@ is ($out, "new\nregister_object foo Foo::Object\n",
is ($err, "some error\n", 'Error handling succeeds for register verifier');
is ($out, "new\nregister_verifier foo Foo::Verifier\n",
' and calls the right methods');
-
-# Test empty lists.
-$Wallet::Admin::error = 0;
-$Wallet::Admin::empty = 1;
-($out, $err) = run_admin ('list', 'objects');
-is ($err, '', 'list objects runs with an empty list with no errors');
-is ($out, "new\nlist_objects\n", ' and calls the right methods');
-($out, $err) = run_admin ('list', 'acls');
-is ($err, '', 'list acls runs with an empty list and no errors');
-is ($out, "new\nlist_acls\n", ' and calls the right methods');
diff --git a/tests/server/backend-t.in b/tests/server/backend-t
index e1518d8..b58d02c 100644..100755
--- a/tests/server/backend-t.in
+++ b/tests/server/backend-t
@@ -1,15 +1,15 @@
#!/usr/bin/perl -w
-# $Id$
#
# Tests for the wallet-backend dispatch code.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2006, 2007, 2008, 2009, 2010
+# Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
use strict;
-use Test::More tests => 1263;
+use Test::More tests => 1269;
# Create a dummy class for Wallet::Server that prints what method was called
# with its arguments and returns data for testing.
@@ -163,7 +163,8 @@ package main;
$INC{'Wallet/Server.pm'} = 'FAKE';
my $OUTPUT;
our $SYSLOG = \$OUTPUT;
-eval { do '@abs_top_srcdir@/server/wallet-backend' };
+my $INPUT = '';
+eval { do "$ENV{SOURCE}/../server/wallet-backend" };
# Run the wallet backend. This fun hack takes advantage of the fact that the
# wallet backend is written in Perl so that we can substitute our own
@@ -173,6 +174,8 @@ sub run_backend {
my $result = '';
open (OUTPUT, '>', \$result) or die "cannot create output string: $!\n";
select OUTPUT;
+ close STDIN;
+ open (STDIN, '<', \$INPUT) or die "cannot change stdin: $!\n";
local $| = 1;
eval { command (@args) };
my $error = $@;
@@ -224,7 +227,7 @@ my %commands = (autocreate => [2, 2],
setacl => [4, 4],
setattr => [4, 9],
show => [2, 2],
- store => [3, 3]);
+ store => [2, 3]);
my %acl_commands = (add => [3, 3],
create => [1, 1],
destroy => [1, 1],
@@ -326,6 +329,7 @@ for my $command (qw/autocreate create destroy setacl setattr store/) {
$method ||= $command;
my @extra = ('foo') x ($commands{$command}[0] - 2);
my $extra = @extra ? join (' ', '', @extra) : '';
+ $extra = ' ' if $command eq 'store';
($out, $err) = run_backend ($command, 'type', 'name', @extra);
my $ran;
if ($command eq 'store') {
@@ -339,7 +343,11 @@ for my $command (qw/autocreate create destroy setacl setattr store/) {
is ($out, "$new\n$method type name$extra\n",
' and ran the right method');
($out, $err) = run_backend ($command, 'error', 'name', @extra);
- $ran = "$command error name" . (@extra ? " @extra" : '');
+ if ($command eq 'store') {
+ $ran = "$command error name";
+ } else {
+ $ran = "$command error name" . (@extra ? " @extra" : '');
+ }
is ($err, "error count $error\n", "Command $command ran with errors");
is ($OUTPUT, "command $ran from admin (1.2.3.4) failed: error count"
. " $error\n", ' and syslog correct');
@@ -409,7 +417,7 @@ for my $command (qw/check expires get getacl getattr history owner show/) {
' and ran the right method with output');
}
($out, $err) = run_backend ($command, 'error', 'name', @extra);
- my $ran = "$command error name" . (@extra ? " @extra" : '');
+ $ran = "$command error name" . (@extra ? " @extra" : '');
is ($err, "error count $error\n", "Command $command ran with errors");
is ($OUTPUT, "command $ran from admin (1.2.3.4) failed: error count"
. " $error\n", ' and syslog correct');
@@ -464,6 +472,22 @@ for my $command (sort keys %flag_commands) {
$error++;
}
+# Special check for store allowing nul characters on standard input.
+$INPUT = "Some data\000with a nul character";
+($out, $err) = run_backend ('store', 'type', 'name');
+is ($err, '', 'store with nul data ran with no errors');
+is ($OUTPUT, "command store type name from admin (1.2.3.4) succeeded\n",
+ ' and success logged');
+is ($out, "$new\nstore type name $INPUT\n",
+ ' and ran the right method');
+$INPUT = '';
+($out, $err) = run_backend ('store', 'type', 'name');
+is ($err, '', 'store with empty stdin data ran with no errors');
+is ($OUTPUT, "command store type name from admin (1.2.3.4) succeeded\n",
+ ' and success logged');
+is ($out, "$new\nstore type name \n",
+ ' and ran the right method');
+
# Almost done. All that remains is to test the robustness of the bad
# character checks against every possible character and test permitting the
# empty argument.
diff --git a/tests/server/keytab-t.in b/tests/server/keytab-t
index f74267d..2a0ceed 100644..100755
--- a/tests/server/keytab-t.in
+++ b/tests/server/keytab-t
@@ -1,10 +1,9 @@
#!/usr/bin/perl -w
-# $Id: backend-t.in 3547 2007-09-14 23:18:48Z rra $
#
# Tests for the keytab-backend dispatch code.
#
# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2006, 2007 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2006, 2007, 2010 Board of Trustees, Leland Stanford Jr. University
#
# See LICENSE for licensing terms.
@@ -16,9 +15,9 @@ use Test::More tests => 63;
# Load the keytab-backend code and override various settings.
my $OUTPUT;
$SYSLOG = \$OUTPUT;
-eval { do '@abs_top_srcdir@/server/keytab-backend' };
-$CONFIG = '@abs_top_srcdir@/tests/data/allow-extract';
-$KADMIN = '@abs_top_srcdir@/tests/data/fake-kadmin';
+eval { do "$ENV{SOURCE}/../server/keytab-backend" };
+$CONFIG = "$ENV{SOURCE}/data/allow-extract";
+$KADMIN = "$ENV{SOURCE}/data/fake-kadmin";
$TMP = '.';
# Run the keytab backend.
diff --git a/tests/server/pod-t.in b/tests/server/pod-t.in
deleted file mode 100644
index fd939a5..0000000
--- a/tests/server/pod-t.in
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/perl
-# $Id$
-#
-# tests/server/pod-t -- Test POD formatting for client documentation.
-#
-# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2008 Board of Trustees, Leland Stanford Jr. University
-#
-# See LICENSE for licensing terms.
-
-use Test::More;
-
-my @files = qw(keytab-backend wallet-admin wallet-backend);
-my $total = scalar (@files);
-plan tests => $total;
-
-eval 'use Test::Pod 1.00';
-SKIP: {
- skip $total, 'Test::Pod 1.00 required for testing POD' if $@;
- for my $file (@files) {
- pod_file_ok ("@abs_top_srcdir@/server/$file", "server/$file");
- }
-}
diff --git a/tests/server/report-t b/tests/server/report-t
new file mode 100755
index 0000000..285ee5a
--- /dev/null
+++ b/tests/server/report-t
@@ -0,0 +1,151 @@
+#!/usr/bin/perl -w
+#
+# Tests for the wallet-report dispatch code.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+use strict;
+use Test::More tests => 32;
+
+# Create a dummy class for Wallet::Report that prints what method was called
+# with its arguments and returns data for testing.
+package Wallet::Report;
+
+use vars qw($empty $error);
+$error = 0;
+$empty = 0;
+
+sub error {
+ if ($error) {
+ return "some error";
+ } else {
+ return;
+ }
+}
+
+sub new {
+ print "new\n";
+ return bless ({}, 'Wallet::Report');
+}
+
+sub acls {
+ shift;
+ print "acls @_\n";
+ return if ($error or $empty);
+ return ([ 1, 'ADMIN' ], [ 2, 'group/admins' ], [ 4, 'group/users' ]);
+}
+
+sub objects {
+ shift;
+ print "objects @_\n";
+ return if ($error or $empty);
+ return ([ keytab => 'host/windlord.stanford.edu' ],
+ [ file => 'unix-wallet-password' ]);
+}
+
+sub owners {
+ shift;
+ print "owners @_\n";
+ return if ($error or $empty);
+ return ([ krb5 => 'admin@EXAMPLE.COM' ]);
+}
+
+# Back to the main package and the actual test suite. Lie about whether the
+# Wallet::Report package has already been loaded.
+package main;
+$INC{'Wallet/Report.pm'} = 'FAKE';
+eval { do "$ENV{SOURCE}/../server/wallet-report" };
+
+# Run the wallet report client. This fun hack takes advantage of the fact
+# that the wallet report client is written in Perl so that we can substitute
+# our own Wallet::Report class.
+sub run_report {
+ my (@args) = @_;
+ my $result = '';
+ open (OUTPUT, '>', \$result) or die "cannot create output string: $!\n";
+ select OUTPUT;
+ local $| = 1;
+ eval { command (@args) };
+ my $error = $@;
+ select STDOUT;
+ return ($result, $error);
+}
+
+# Now for the actual tests. First check for unknown commands.
+my ($out, $err) = run_report ('foo');
+is ($err, "unknown command foo\n", 'Unknown command');
+is ($out, "new\n", ' and nothing ran');
+
+# Check too few and too many arguments for every command.
+my %commands = (acls => [0, 3],
+ objects => [0, 2],
+ owners => [2, 2]);
+for my $command (sort keys %commands) {
+ my ($min, $max) = @{ $commands{$command} };
+ if ($min > 0) {
+ ($out, $err) = run_report ($command, ('foo') x ($min - 1));
+ is ($err, "too few arguments to $command\n",
+ "Too few arguments for $command");
+ is ($out, "new\n", ' and nothing ran');
+ }
+ if ($max >= 0) {
+ ($out, $err) = run_report ($command, ('foo') x ($max + 1));
+ is ($err, "too many arguments to $command\n",
+ "Too many arguments for $command");
+ is ($out, "new\n", ' and nothing ran');
+ }
+}
+
+# Test the report methods.
+($out, $err) = run_report ('acls');
+is ($err, '', 'List succeeds for ACLs');
+is ($out, "new\nacls \n"
+ . "ADMIN (ACL ID: 1)\ngroup/admins (ACL ID: 2)\ngroup/users (ACL ID: 4)\n",
+ ' and returns the right output');
+($out, $err) = run_report ('acls', 'entry', 'foo', 'foo');
+is ($err, '', 'List succeeds for ACLs');
+is ($out, "new\nacls entry foo foo\n"
+ . "ADMIN (ACL ID: 1)\ngroup/admins (ACL ID: 2)\ngroup/users (ACL ID: 4)\n",
+ ' and returns the right output');
+($out, $err) = run_report ('objects');
+is ($err, '', 'List succeeds for objects');
+is ($out, "new\nobjects \n"
+ . "keytab host/windlord.stanford.edu\nfile unix-wallet-password\n",
+ ' and returns the right output');
+($out, $err) = run_report ('objects', 'type', 'foo');
+is ($err, '', 'List succeeds for objects type foo');
+is ($out, "new\nobjects type foo\n"
+ . "keytab host/windlord.stanford.edu\nfile unix-wallet-password\n",
+ ' and returns the right output');
+($out, $err) = run_report ('owners', '%', '%');
+is ($err, '', 'Report succeeds for owners');
+is ($out, "new\nowners % %\nkrb5 admin\@EXAMPLE.COM\n",
+ ' and returns the right output');
+
+# Test error handling.
+$Wallet::Report::error = 1;
+($out, $err) = run_report ('acls');
+is ($err, "some error\n", 'Error handling succeeds for list acls');
+is ($out, "new\nacls \n", ' and calls the right methods');
+($out, $err) = run_report ('objects');
+is ($err, "some error\n", 'Error handling succeeds for list objects');
+is ($out, "new\nobjects \n", ' and calls the right methods');
+($out, $err) = run_report ('owners', 'foo', 'bar');
+is ($err, "some error\n", 'Error handling succeeds for report owners');
+is ($out, "new\nowners foo bar\n", ' and calls the right methods');
+
+# Test empty lists.
+$Wallet::Report::error = 0;
+$Wallet::Report::empty = 1;
+($out, $err) = run_report ('acls');
+is ($err, '', 'list acls runs with an empty list and no errors');
+is ($out, "new\nacls \n", ' and calls the right methods');
+($out, $err) = run_report ('objects');
+is ($err, '', 'list objects runs with an empty list with no errors');
+is ($out, "new\nobjects \n", ' and calls the right methods');
+($out, $err) = run_report ('owners', 'foo', 'bar');
+is ($err, '', 'report owners runs with an empty list and no errors');
+is ($out, "new\nowners foo bar\n", ' and calls the right methods');
diff --git a/tests/tap/basic.c b/tests/tap/basic.c
new file mode 100644
index 0000000..5ca9ff4
--- /dev/null
+++ b/tests/tap/basic.c
@@ -0,0 +1,356 @@
+/*
+ * Some utility routines for writing tests.
+ *
+ * Herein are a variety of utility routines for writing tests. All routines
+ * of the form ok*() take a test number and some number of appropriate
+ * arguments, check to be sure the results match the expected output using the
+ * arguments, and print out something appropriate for that test number. Other
+ * utility routines help in constructing more complex tests.
+ *
+ * Copyright 2009 Russ Allbery <rra@stanford.edu>
+ * Copyright 2006, 2007, 2008
+ * Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
+ * by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <tap/basic.h>
+
+/*
+ * The test count. Always contains the number that will be used for the next
+ * test status.
+ */
+int testnum = 1;
+
+/*
+ * Status information stored so that we can give a test summary at the end of
+ * the test case. We store the planned final test and the count of failures.
+ * We can get the highest test count from testnum.
+ *
+ * We also store the PID of the process that called plan() and only summarize
+ * results when that process exits, so as to not misreport results in forked
+ * processes.
+ */
+static int _planned = 0;
+static int _failed = 0;
+static pid_t _process = 0;
+
+
+/*
+ * Our exit handler. Called on completion of the test to report a summary of
+ * results provided we're still in the original process.
+ */
+static void
+finish(void)
+{
+ int highest = testnum - 1;
+
+ if (_process != 0 && getpid() == _process && _planned > 0) {
+ if (_planned > highest)
+ printf("# Looks like you planned %d test%s but only ran %d\n",
+ _planned, (_planned > 1 ? "s" : ""), highest);
+ else if (_planned < highest)
+ printf("# Looks like you planned %d test%s but ran %d extra\n",
+ _planned, (_planned > 1 ? "s" : ""), highest - _planned);
+ else if (_failed > 0)
+ printf("# Looks like you failed %d test%s of %d\n", _failed,
+ (_failed > 1 ? "s" : ""), _planned);
+ else if (_planned > 1)
+ printf("# All %d tests successful or skipped\n", _planned);
+ else
+ printf("# %d test successful or skipped\n", _planned);
+ }
+}
+
+
+/*
+ * Initialize things. Turns on line buffering on stdout and then prints out
+ * the number of tests in the test suite.
+ */
+void
+plan(int count)
+{
+ if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
+ fprintf(stderr, "# cannot set stdout to line buffered: %s\n",
+ strerror(errno));
+ printf("1..%d\n", count);
+ testnum = 1;
+ _planned = count;
+ _process = getpid();
+ atexit(finish);
+}
+
+
+/*
+ * Skip the entire test suite and exits. Should be called instead of plan(),
+ * not after it, since it prints out a special plan line.
+ */
+void
+skip_all(const char *format, ...)
+{
+ printf("1..0 # skip");
+ if (format != NULL) {
+ va_list args;
+
+ putchar(' ');
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+ }
+ putchar('\n');
+ exit(0);
+}
+
+
+/*
+ * Print the test description.
+ */
+static void
+print_desc(const char *format, va_list args)
+{
+ printf(" - ");
+ vprintf(format, args);
+}
+
+
+/*
+ * Takes a boolean success value and assumes the test passes if that value
+ * is true and fails if that value is false.
+ */
+void
+ok(int success, const char *format, ...)
+{
+ printf("%sok %d", success ? "" : "not ", testnum++);
+ if (!success)
+ _failed++;
+ if (format != NULL) {
+ va_list args;
+
+ va_start(args, format);
+ print_desc(format, args);
+ va_end(args);
+ }
+ putchar('\n');
+}
+
+
+/*
+ * Skip a test.
+ */
+void
+skip(const char *reason, ...)
+{
+ printf("ok %d # skip", testnum++);
+ if (reason != NULL) {
+ va_list args;
+
+ va_start(args, reason);
+ putchar(' ');
+ vprintf(reason, args);
+ va_end(args);
+ }
+ putchar('\n');
+}
+
+
+/*
+ * Report the same status on the next count tests.
+ */
+void
+ok_block(int count, int status, const char *format, ...)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ printf("%sok %d", status ? "" : "not ", testnum++);
+ if (!status)
+ _failed++;
+ if (format != NULL) {
+ va_list args;
+
+ va_start(args, format);
+ print_desc(format, args);
+ va_end(args);
+ }
+ putchar('\n');
+ }
+}
+
+
+/*
+ * Skip the next count tests.
+ */
+void
+skip_block(int count, const char *reason, ...)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ printf("ok %d # skip", testnum++);
+ if (reason != NULL) {
+ va_list args;
+
+ va_start(args, reason);
+ putchar(' ');
+ vprintf(reason, args);
+ va_end(args);
+ }
+ putchar('\n');
+ }
+}
+
+
+/*
+ * Takes an expected integer and a seen integer and assumes the test passes
+ * if those two numbers match.
+ */
+void
+is_int(int wanted, int seen, const char *format, ...)
+{
+ if (wanted == seen)
+ printf("ok %d", testnum++);
+ else {
+ printf("# wanted: %d\n# seen: %d\n", wanted, seen);
+ printf("not ok %d", testnum++);
+ _failed++;
+ }
+ if (format != NULL) {
+ va_list args;
+
+ va_start(args, format);
+ print_desc(format, args);
+ va_end(args);
+ }
+ putchar('\n');
+}
+
+
+/*
+ * Takes a string and what the string should be, and assumes the test passes
+ * if those strings match (using strcmp).
+ */
+void
+is_string(const char *wanted, const char *seen, const char *format, ...)
+{
+ if (wanted == NULL)
+ wanted = "(null)";
+ if (seen == NULL)
+ seen = "(null)";
+ if (strcmp(wanted, seen) == 0)
+ printf("ok %d", testnum++);
+ else {
+ printf("# wanted: %s\n# seen: %s\n", wanted, seen);
+ printf("not ok %d", testnum++);
+ _failed++;
+ }
+ if (format != NULL) {
+ va_list args;
+
+ va_start(args, format);
+ print_desc(format, args);
+ va_end(args);
+ }
+ putchar('\n');
+}
+
+
+/*
+ * Takes an expected double and a seen double and assumes the test passes if
+ * those two numbers match.
+ */
+void
+is_double(double wanted, double seen, const char *format, ...)
+{
+ if (wanted == seen)
+ printf("ok %d", testnum++);
+ else {
+ printf("# wanted: %g\n# seen: %g\n", wanted, seen);
+ printf("not ok %d", testnum++);
+ _failed++;
+ }
+ if (format != NULL) {
+ va_list args;
+
+ va_start(args, format);
+ print_desc(format, args);
+ va_end(args);
+ }
+ putchar('\n');
+}
+
+
+/*
+ * Takes an expected unsigned long and a seen unsigned long and assumes the
+ * test passes if the two numbers match. Otherwise, reports them in hex.
+ */
+void
+is_hex(unsigned long wanted, unsigned long seen, const char *format, ...)
+{
+ if (wanted == seen)
+ printf("ok %d", testnum++);
+ else {
+ printf("# wanted: %lx\n# seen: %lx\n", (unsigned long) wanted,
+ (unsigned long) seen);
+ printf("not ok %d", testnum++);
+ _failed++;
+ }
+ if (format != NULL) {
+ va_list args;
+
+ va_start(args, format);
+ print_desc(format, args);
+ va_end(args);
+ }
+ putchar('\n');
+}
+
+
+/*
+ * Bail out with an error.
+ */
+void
+bail(const char *format, ...)
+{
+ va_list args;
+
+ fflush(stdout);
+ printf("Bail out! ");
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+ printf("\n");
+ exit(1);
+}
+
+
+/*
+ * Bail out with an error, appending strerror(errno).
+ */
+void
+sysbail(const char *format, ...)
+{
+ va_list args;
+ int oerrno = errno;
+
+ fflush(stdout);
+ printf("Bail out! ");
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+ printf(": %s\n", strerror(oerrno));
+ exit(1);
+}
diff --git a/tests/tap/basic.h b/tests/tap/basic.h
new file mode 100644
index 0000000..efe94ba
--- /dev/null
+++ b/tests/tap/basic.h
@@ -0,0 +1,98 @@
+/*
+ * Basic utility routines for the TAP protocol.
+ *
+ * Copyright 2006, 2007, 2008
+ * Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
+ * by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#ifndef TAP_BASIC_H
+#define TAP_BASIC_H 1
+
+#include <sys/types.h> /* pid_t */
+
+/*
+ * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7
+ * could you use the __format__ form of the attributes, which is what we use
+ * (to avoid confusion with other macros).
+ */
+#ifndef __attribute__
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+# define __attribute__(spec) /* empty */
+# endif
+#endif
+
+/*
+ * BEGIN_DECLS is used at the beginning of declarations so that C++
+ * compilers don't mangle their names. END_DECLS is used at the end.
+ */
+#undef BEGIN_DECLS
+#undef END_DECLS
+#ifdef __cplusplus
+# define BEGIN_DECLS extern "C" {
+# define END_DECLS }
+#else
+# define BEGIN_DECLS /* empty */
+# define END_DECLS /* empty */
+#endif
+
+/*
+ * Used for iterating through arrays. ARRAY_SIZE returns the number of
+ * elements in the array (useful for a < upper bound in a for loop) and
+ * ARRAY_END returns a pointer to the element past the end (ISO C99 makes it
+ * legal to refer to such a pointer as long as it's never dereferenced).
+ */
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+#define ARRAY_END(array) (&(array)[ARRAY_SIZE(array)])
+
+BEGIN_DECLS
+
+/*
+ * The test count. Always contains the number that will be used for the next
+ * test status.
+ */
+extern int testnum;
+
+/* Print out the number of tests and set standard output to line buffered. */
+void plan(int count);
+
+/* Skip the entire test suite. Call instead of plan. */
+void skip_all(const char *format, ...)
+ __attribute__((__noreturn__, __format__(printf, 1, 2)));
+
+/* Basic reporting functions. */
+void ok(int success, const char *format, ...)
+ __attribute__((__format__(printf, 2, 3)));
+void skip(const char *reason, ...)
+ __attribute__((__format__(printf, 1, 2)));
+
+/* Report the same status on, or skip, the next count tests. */
+void ok_block(int count, int success, const char *format, ...)
+ __attribute__((__format__(printf, 3, 4)));
+void skip_block(int count, const char *reason, ...)
+ __attribute__((__format__(printf, 2, 3)));
+
+/* Check an expected value against a seen value. */
+void is_int(int wanted, int seen, const char *format, ...)
+ __attribute__((__format__(printf, 3, 4)));
+void is_double(double wanted, double seen, const char *format, ...)
+ __attribute__((__format__(printf, 3, 4)));
+void is_string(const char *wanted, const char *seen, const char *format, ...)
+ __attribute__((__format__(printf, 3, 4)));
+void is_hex(unsigned long wanted, unsigned long seen, const char *format, ...)
+ __attribute__((__format__(printf, 3, 4)));
+
+/* Bail out with an error. sysbail appends strerror(errno). */
+void bail(const char *format, ...)
+ __attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2)));
+void sysbail(const char *format, ...)
+ __attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2)));
+
+END_DECLS
+
+#endif /* LIBTEST_H */
diff --git a/tests/tap/kerberos.c b/tests/tap/kerberos.c
new file mode 100644
index 0000000..700212e
--- /dev/null
+++ b/tests/tap/kerberos.c
@@ -0,0 +1,164 @@
+/*
+ * Utility functions for tests that use Kerberos.
+ *
+ * Currently only provides kerberos_setup(), which assumes a particular set of
+ * data files in either the SOURCE or BUILD directories and, using those,
+ * obtains Kerberos credentials, sets up a ticket cache, and sets the
+ * environment variable pointing to the Kerberos keytab to use for testing.
+ *
+ * Copyright 2006, 2007, 2009, 2010
+ * Board of Trustees, Leland Stanford Jr. University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <config.h>
+#include <portable/krb5.h>
+#include <portable/system.h>
+
+#include <tests/tap/basic.h>
+#include <tests/tap/kerberos.h>
+#include <util/concat.h>
+#include <util/xmalloc.h>
+
+
+/*
+ * Given the partial path to a file, look under BUILD and then SOURCE for the
+ * file and return the full path to the file in newly-allocated memory.
+ * Returns NULL if the file doesn't exist.
+ */
+static char *
+find_file(const char *file)
+{
+ char *base;
+ char *path = NULL;
+ const char *envs[] = { "BUILD", "SOURCE", NULL };
+ int i;
+
+ for (i = 0; envs[i] != NULL; i++) {
+ base = getenv(envs[i]);
+ if (base == NULL)
+ continue;
+ path = concatpath(base, file);
+ if (access(path, R_OK) == 0)
+ break;
+ free(path);
+ path = NULL;
+ }
+ return path;
+}
+
+
+/*
+ * Obtain Kerberos tickets for the principal specified in test.principal using
+ * the keytab specified in test.keytab, both of which are presumed to be in
+ * tests/data in either the build or the source tree.
+ *
+ * Returns the contents of test.principal in newly allocated memory or NULL if
+ * Kerberos tests are apparently not configured. If Kerberos tests are
+ * configured but something else fails, calls bail().
+ *
+ * The error handling here is not great. We should have a bail_krb5 that uses
+ * the same logic as messages-krb5.c, which hasn't yet been imported into
+ * rra-c-util.
+ */
+char *
+kerberos_setup(void)
+{
+ char *path, *krbtgt;
+ const char *build, *realm;
+ FILE *file;
+ char principal[BUFSIZ];
+ krb5_error_code code;
+ krb5_context ctx;
+ krb5_ccache ccache;
+ krb5_principal kprinc;
+ krb5_keytab keytab;
+ krb5_get_init_creds_opt *opts;
+ krb5_creds creds;
+
+ /* Read the principal name and find the keytab file. */
+ path = find_file("data/test.principal");
+ if (path == NULL)
+ return NULL;
+ file = fopen(path, "r");
+ if (file == NULL) {
+ free(path);
+ return NULL;
+ }
+ if (fgets(principal, sizeof(principal), file) == NULL) {
+ fclose(file);
+ bail("cannot read %s", path);
+ }
+ fclose(file);
+ if (principal[strlen(principal) - 1] != '\n')
+ bail("no newline in %s", path);
+ free(path);
+ principal[strlen(principal) - 1] = '\0';
+ path = find_file("data/test.keytab");
+ if (path == NULL)
+ return NULL;
+
+ /* Set the KRB5CCNAME and KRB5_KTNAME environment variables. */
+ build = getenv("BUILD");
+ if (build == NULL)
+ build = ".";
+ putenv(concat("KRB5CCNAME=", build, "/data/test.cache", (char *) 0));
+ putenv(concat("KRB5_KTNAME=", path, (char *) 0));
+
+ /* Now do the Kerberos initialization. */
+ code = krb5_init_context(&ctx);
+ if (code != 0)
+ bail("error initializing Kerberos");
+ code = krb5_cc_default(ctx, &ccache);
+ if (code != 0)
+ bail("error setting ticket cache");
+ code = krb5_parse_name(ctx, principal, &kprinc);
+ if (code != 0)
+ bail("error parsing principal %s", principal);
+ realm = krb5_principal_get_realm(ctx, kprinc);
+ krbtgt = concat("krbtgt/", realm, "@", realm, (char *) 0);
+ code = krb5_kt_resolve(ctx, path, &keytab);
+ if (code != 0)
+ bail("cannot open keytab %s", path);
+ code = krb5_get_init_creds_opt_alloc(ctx, &opts);
+ if (code != 0)
+ bail("cannot allocate credential options");
+ krb5_get_init_creds_opt_set_default_flags(ctx, NULL, realm, opts);
+ krb5_get_init_creds_opt_set_forwardable(opts, 0);
+ krb5_get_init_creds_opt_set_proxiable(opts, 0);
+ code = krb5_get_init_creds_keytab(ctx, &creds, kprinc, keytab, 0, krbtgt,
+ opts);
+ if (code != 0)
+ bail("cannot get Kerberos tickets");
+ code = krb5_cc_initialize(ctx, ccache, kprinc);
+ if (code != 0)
+ bail("error initializing ticket cache");
+ code = krb5_cc_store_cred(ctx, ccache, &creds);
+ if (code != 0)
+ bail("error storing credentials");
+ krb5_cc_close(ctx, ccache);
+ krb5_free_cred_contents(ctx, &creds);
+ krb5_kt_close(ctx, keytab);
+ krb5_free_principal(ctx, kprinc);
+ krb5_free_context(ctx);
+ free(krbtgt);
+ free(path);
+
+ return xstrdup(principal);
+}
+
+
+/*
+ * Clean up at the end of a test. Currently, all this does is remove the
+ * ticket cache.
+ */
+void
+kerberos_cleanup(void)
+{
+ char *path;
+
+ path = concatpath(getenv("BUILD"), "data/test.cache");
+ unlink(path);
+ free(path);
+}
diff --git a/tests/tap/kerberos.h b/tests/tap/kerberos.h
new file mode 100644
index 0000000..1c64f70
--- /dev/null
+++ b/tests/tap/kerberos.h
@@ -0,0 +1,32 @@
+/*
+ * Utility functions for tests that use Kerberos.
+ *
+ * Copyright 2006, 2007, 2009
+ * Board of Trustees, Leland Stanford Jr. University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#ifndef TAP_KERBEROS_H
+#define TAP_KERBEROS_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+BEGIN_DECLS
+
+/*
+ * Set up Kerberos, returning the test principal in newly allocated memory if
+ * we were successful. If there is no principal in tests/data/test.principal
+ * or no keytab in tests/data/test.keytab, return NULL. Otherwise, on
+ * failure, calls bail().
+ */
+char *kerberos_setup(void)
+ __attribute__((__malloc__));
+
+/* Clean up at the end of a test. */
+void kerberos_cleanup(void);
+
+END_DECLS
+
+#endif /* !TAP_MESSAGES_H */
diff --git a/tests/tap/kerberos.sh b/tests/tap/kerberos.sh
new file mode 100644
index 0000000..da07e66
--- /dev/null
+++ b/tests/tap/kerberos.sh
@@ -0,0 +1,48 @@
+# Shell function library to initialize Kerberos credentials
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2009 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+# Set up Kerberos, including the ticket cache environment variable. Bail out
+# if not successful, return 0 if successful, and return 1 if Kerberos is not
+# configured. Sets the global principal variable to the principal to use.
+kerberos_setup () {
+ local keytab
+ keytab=''
+ for f in "$BUILD/data/test.keytab" "$SOURCE/data/test.keytab" ; do
+ if [ -r "$f" ] ; then
+ keytab="$f"
+ fi
+ done
+ principal=''
+ for f in "$BUILD/data/test.principal" "$SOURCE/data/test.principal" ; do
+ if [ -r "$f" ] ; then
+ principal=`cat "$BUILD/data/test.principal"`
+ fi
+ done
+ if [ -z "$keytab" ] || [ -z "$principal" ] ; then
+ return 1
+ fi
+ KRB5CCNAME="$BUILD/data/test.cache"; export KRB5CCNAME
+ kinit -k -t "$keytab" "$principal" >/dev/null </dev/null
+ status=$?
+ if [ $status != 0 ] ; then
+ kinit -t "$keytab" "$principal" >/dev/null </dev/null
+ status=$?
+ fi
+ if [ $status != 0 ] ; then
+ kinit -k -K "$keytab" "$principal" >/dev/null </dev/null
+ status=$?
+ fi
+ if [ $status != 0 ] ; then
+ bail "Can't get Kerberos tickets"
+ fi
+ return 0
+}
+
+# Clean up at the end of a test. Currently only removes the ticket cache.
+kerberos_cleanup () {
+ rm -f "$BUILD/data/test.cache"
+}
diff --git a/tests/tap/libtap.sh b/tests/tap/libtap.sh
new file mode 100644
index 0000000..1846840
--- /dev/null
+++ b/tests/tap/libtap.sh
@@ -0,0 +1,148 @@
+# Shell function library for test cases.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2009 Russ Allbery <rra@stanford.edu>
+# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+# Print out the number of test cases we expect to run.
+plan () {
+ count=1
+ planned="$1"
+ failed=0
+ echo "1..$1"
+ trap finish 0
+}
+
+# Report the test status on exit.
+finish () {
+ local highest looks
+ highest=`expr "$count" - 1`
+ looks='# Looks like you'
+ if [ "$planned" -gt 0 ] ; then
+ if [ "$planned" -gt "$highest" ] ; then
+ if [ "$planned" -gt 1 ] ; then
+ echo "$looks planned $planned tests but only ran $highest"
+ else
+ echo "$looks planned $planned test but only ran $highest"
+ fi
+ elif [ "$planned" -lt "$highest" ] ; then
+ local extra
+ extra=`expr "$highest" - "$planned"`
+ if [ "$planned" -gt 1 ] ; then
+ echo "$looks planned $planned tests but ran $extra extra"
+ else
+ echo "$looks planned $planned test but ran $extra extra"
+ fi
+ elif [ "$failed" -gt 0 ] ; then
+ if [ "$failed" -gt 1 ] ; then
+ echo "$looks failed $failed tests of $planned"
+ else
+ echo "$looks failed $failed test of $planned"
+ fi
+ elif [ "$planned" -gt 1 ] ; then
+ echo "# All $planned tests successful or skipped"
+ else
+ echo "# $planned test successful or skipped"
+ fi
+ fi
+}
+
+# Skip the entire test suite. Should be run instead of plan.
+skip_all () {
+ local desc
+ desc="$1"
+ if [ -n "$desc" ] ; then
+ echo "1..0 # skip $desc"
+ else
+ echo "1..0 # skip"
+ fi
+ exit 0
+}
+
+# ok takes a test description and a command to run and prints success if that
+# command is successful, false otherwise. The count starts at 1 and is
+# updated each time ok is printed.
+ok () {
+ local desc
+ desc="$1"
+ if [ -n "$desc" ] ; then
+ desc=" - $desc"
+ fi
+ shift
+ if "$@" ; then
+ echo ok $count$desc
+ else
+ echo not ok $count$desc
+ failed=`expr $failed + 1`
+ fi
+ count=`expr $count + 1`
+}
+
+# Skip the next test. Takes the reason why the test is skipped.
+skip () {
+ echo "ok $count # skip $*"
+ count=`expr $count + 1`
+}
+
+# Report the same status on a whole set of tests. Takes the count of tests,
+# the description, and then the command to run to determine the status.
+ok_block () {
+ local end i desc
+ i=$count
+ end=`expr $count + $1`
+ shift
+ desc="$1"
+ shift
+ while [ "$i" -lt "$end" ] ; do
+ ok "$desc" "$@"
+ i=`expr $i + 1`
+ done
+}
+
+# Skip a whole set of tests. Takes the count and then the reason for skipping
+# the test.
+skip_block () {
+ local i end
+ i=$count
+ end=`expr $count + $1`
+ shift
+ while [ "$i" -lt "$end" ] ; do
+ skip "$@"
+ i=`expr $i + 1`
+ done
+}
+
+# Run a program expected to succeed, and print ok if it does and produces the
+# correct output. Takes the description, expected exit status, the expected
+# output, the command to run, and then any arguments for that command. Strip
+# a colon and everything after it off the output if the expected status is
+# non-zero, since this is probably a system-specific error message.
+ok_program () {
+ local desc w_status w_output output status
+ desc="$1"
+ shift
+ w_status="$1"
+ shift
+ w_output="$1"
+ shift
+ output=`"$@" 2>&1`
+ status=$?
+ if [ "$w_status" -ne 0 ] ; then
+ output=`echo "$output" | sed 's/^\([^:]* [^:]*\):.*/\1/'`
+ fi
+ if [ $status = $w_status ] && [ x"$output" = x"$w_output" ] ; then
+ ok "$desc" true
+ else
+ echo "# saw: ($status) $output"
+ echo "# not: ($w_status) $w_output"
+ ok "$desc" false
+ fi
+}
+
+# Bail out with an error message.
+bail () {
+ echo 'Bail out!' "$@"
+ exit 1
+}
diff --git a/tests/tap/messages.c b/tests/tap/messages.c
new file mode 100644
index 0000000..3bb9a1a
--- /dev/null
+++ b/tests/tap/messages.c
@@ -0,0 +1,80 @@
+/*
+ * Utility functions to test message handling.
+ *
+ * These functions set up a message handler to trap warn and notice output
+ * into a buffer that can be inspected later, allowing testing of error
+ * handling.
+ *
+ * Copyright 2006, 2007, 2009
+ * Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
+ * by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <tests/tap/messages.h>
+#include <util/concat.h>
+#include <util/macros.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
+
+/* A global buffer into which message_log_buffer stores error messages. */
+char *errors = NULL;
+
+
+/*
+ * An error handler that appends all errors to the errors global. Used by
+ * error_capture.
+ */
+static void
+message_log_buffer(int len, const char *fmt, va_list args, int error UNUSED)
+{
+ char *message;
+
+ message = xmalloc(len + 1);
+ vsnprintf(message, len + 1, fmt, args);
+ if (errors == NULL) {
+ errors = concat(message, "\n", (char *) 0);
+ } else {
+ char *new_errors;
+
+ new_errors = concat(errors, message, "\n", (char *) 0);
+ free(errors);
+ errors = new_errors;
+ }
+ free(message);
+}
+
+
+/*
+ * Turn on the capturing of errors. Errors will be stored in the global
+ * errors variable where they can be checked by the test suite. Capturing is
+ * turned off with errors_uncapture.
+ */
+void
+errors_capture(void)
+{
+ if (errors != NULL) {
+ free(errors);
+ errors = NULL;
+ }
+ message_handlers_warn(1, message_log_buffer);
+ message_handlers_notice(1, message_log_buffer);
+}
+
+
+/*
+ * Turn off the capturing of errors again.
+ */
+void
+errors_uncapture(void)
+{
+ message_handlers_warn(1, message_log_stderr);
+ message_handlers_notice(1, message_log_stdout);
+}
diff --git a/tests/tap/messages.h b/tests/tap/messages.h
new file mode 100644
index 0000000..2b9a7db
--- /dev/null
+++ b/tests/tap/messages.h
@@ -0,0 +1,35 @@
+/*
+ * Utility functions to test message handling.
+ *
+ * Copyright 2006, 2007, 2009
+ * Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
+ * by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#ifndef TAP_MESSAGES_H
+#define TAP_MESSAGES_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+/* A global buffer into which errors_capture stores errors. */
+extern char *errors;
+
+BEGIN_DECLS
+
+/*
+ * Turn on capturing of errors with errors_capture. Errors reported by warn
+ * will be stored in the global errors variable. Turn this off again with
+ * errors_uncapture. Caller is responsible for freeing errors when done.
+ */
+void errors_capture(void);
+void errors_uncapture(void);
+
+END_DECLS
+
+#endif /* !TAP_MESSAGES_H */
diff --git a/tests/tap/process.c b/tests/tap/process.c
new file mode 100644
index 0000000..16154c7
--- /dev/null
+++ b/tests/tap/process.c
@@ -0,0 +1,100 @@
+/*
+ * Utility functions for tests that use subprocesses.
+ *
+ * Provides utility functions for subprocess manipulation. Currently, only
+ * one utility function is provided: is_function_output, which runs a function
+ * in a subprocess and checks its output and exit status against expected
+ * values.
+ *
+ * Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
+ * by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <sys/wait.h>
+
+#include <tests/tap/basic.h>
+#include <tests/tap/process.h>
+#include <util/xmalloc.h>
+
+
+/*
+ * Given a function, an expected exit status, and expected output, runs that
+ * function in a subprocess, capturing stdout and stderr via a pipe, and
+ * compare the combination of stdout and stderr with the expected output and
+ * the exit status with the expected status. Expects the function to always
+ * exit (not die from a signal).
+ */
+void
+is_function_output(test_function_type function, int status, const char *output,
+ const char *format, ...)
+{
+ int fds[2];
+ pid_t child;
+ char *buf, *msg;
+ ssize_t count, ret, buflen;
+ int rval;
+ va_list args;
+
+ /* Flush stdout before we start to avoid odd forking issues. */
+ fflush(stdout);
+
+ /* Set up the pipe and call the function, collecting its output. */
+ if (pipe(fds) == -1)
+ sysbail("can't create pipe");
+ child = fork();
+ if (child == (pid_t) -1) {
+ sysbail("can't fork");
+ } else if (child == 0) {
+ /* In child. Set up our stdout and stderr. */
+ close(fds[0]);
+ if (dup2(fds[1], 1) == -1)
+ _exit(255);
+ if (dup2(fds[1], 2) == -1)
+ _exit(255);
+
+ /* Now, run the function and exit successfully if it returns. */
+ (*function)();
+ fflush(stdout);
+ _exit(0);
+ } else {
+ /*
+ * In the parent; close the extra file descriptor, read the output if
+ * any, and then collect the exit status.
+ */
+ close(fds[1]);
+ buflen = BUFSIZ;
+ buf = xmalloc(buflen);
+ count = 0;
+ do {
+ ret = read(fds[0], buf + count, buflen - count - 1);
+ if (ret > 0)
+ count += ret;
+ if (count >= buflen - 1) {
+ buflen += BUFSIZ;
+ buf = xrealloc(buf, buflen);
+ }
+ } while (ret > 0);
+ buf[count < 0 ? 0 : count] = '\0';
+ if (waitpid(child, &rval, 0) == (pid_t) -1)
+ sysbail("waitpid failed");
+ }
+
+ /* Now, check the results against what we expected. */
+ va_start(args, format);
+ if (xvasprintf(&msg, format, args) < 0)
+ bail("cannot format test description");
+ va_end(args);
+ ok(WIFEXITED(rval), "%s (exited)", msg);
+ is_int(status, WEXITSTATUS(rval), "%s (status)", msg);
+ is_string(output, buf, "%s (output)", msg);
+ free(buf);
+ free(msg);
+}
diff --git a/tests/tap/process.h b/tests/tap/process.h
new file mode 100644
index 0000000..b7d3b11
--- /dev/null
+++ b/tests/tap/process.h
@@ -0,0 +1,37 @@
+/*
+ * Utility functions for tests that use subprocesses.
+ *
+ * Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
+ * by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#ifndef TAP_PROCESS_H
+#define TAP_PROCESS_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+BEGIN_DECLS
+
+/*
+ * Run a function in a subprocess and check the exit status and expected
+ * output (stdout and stderr combined) against the provided values. Expects
+ * the function to always exit (not die from a signal).
+ *
+ * This reports as three separate tests: whether the function exited rather
+ * than was killed, whether the exit status was correct, and whether the
+ * output was correct.
+ */
+typedef void (*test_function_type)(void);
+void is_function_output(test_function_type, int status, const char *output,
+ const char *format, ...)
+ __attribute__((__format__(printf, 4, 5)));
+
+END_DECLS
+
+#endif /* TAP_PROCESS_H */
diff --git a/tests/tap/remctl.sh b/tests/tap/remctl.sh
new file mode 100644
index 0000000..b9667ef
--- /dev/null
+++ b/tests/tap/remctl.sh
@@ -0,0 +1,46 @@
+# Shell function library to start and stop remctld
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2009 Board of Trustees, Leland Stanford Jr. University
+#
+# See LICENSE for licensing terms.
+
+# Start remctld. Takes the path to remctld, which may be found via configure,
+# and the path to the configuration file.
+remctld_start () {
+ local keytab principal
+ rm -f "$BUILD/data/remctld.pid"
+ keytab=''
+ for f in "$BUILD/data/test.keytab" "$SOURCE/data/test.keytab" ; do
+ if [ -r "$f" ] ; then
+ keytab="$f"
+ fi
+ done
+ principal=''
+ for f in "$BUILD/data/test.principal" "$SOURCE/data/test.principal" ; do
+ if [ -r "$f" ] ; then
+ principal=`cat "$BUILD/data/test.principal"`
+ fi
+ done
+ if [ -n "$VALGRIND" ] ; then
+ ( "$VALGRIND" --log-file=valgrind.%p --leak-check=full "$1" -m \
+ -p 14373 -s "$principal" -P "$BUILD/data/remctld.pid" -f "$2" -d \
+ -S -F -k "$keytab" &)
+ [ -f "$BUILD/data/remctld.pid" ] || sleep 5
+ else
+ ( "$1" -m -p 14373 -s "$principal" -P "$BUILD/data/remctld.pid" \
+ -f "$2" -d -S -F -k "$keytab" &)
+ fi
+ [ -f "$BUILD/data/remctld.pid" ] || sleep 1
+ if [ ! -f "$BUILD/data/remctld.pid" ] ; then
+ bail 'remctld did not start'
+ fi
+}
+
+# Stop remctld and clean up.
+remctld_stop () {
+ if [ -f "$BUILD/data/remctld.pid" ] ; then
+ kill -TERM `cat "$BUILD/data/remctld.pid"`
+ rm -f "$BUILD/data/remctld.pid"
+ fi
+}
diff --git a/tests/util/concat-t.c b/tests/util/concat-t.c
index 2428d71..ca7de2c 100644
--- a/tests/util/concat-t.c
+++ b/tests/util/concat-t.c
@@ -1,59 +1,46 @@
-/* $Id$
- *
+/*
* concat test suite.
*
- * Copyright 2004, 2005, 2006
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2009 Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
- * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- * 2003 by The Internet Software Consortium and Rich Salz
- *
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * See LICENSE for licensing terms.
*/
#include <config.h>
#include <portable/system.h>
-#include <tests/libtest.h>
-#include <util/util.h>
+#include <tests/tap/basic.h>
+#include <util/concat.h>
#define END (char *) 0
-
/*
* Memory leaks everywhere! Whoo-hoo!
*/
int
main(void)
{
- test_init(13);
-
- ok_string( 1, "a", concat("a", END));
- ok_string( 2, "ab", concat("a", "b", END));
- ok_string( 3, "ab", concat("ab", "", END));
- ok_string( 4, "ab", concat("", "ab", END));
- ok_string( 5, "", concat("", END));
- ok_string( 6, "abcde", concat("ab", "c", "", "de", END));
- ok_string( 7, "abcde", concat("abc", "de", END, "f", END));
-
- ok_string( 8, "/foo", concatpath("/bar", "/foo"));
- ok_string( 9, "/foo/bar", concatpath("/foo", "bar"));
- ok_string(10, "./bar", concatpath("/foo", "./bar"));
- ok_string(11, "/bar/baz/foo/bar", concatpath("/bar/baz", "foo/bar"));
- ok_string(12, "./foo", concatpath(NULL, "foo"));
- ok_string(13, "/foo/bar", concatpath(NULL, "/foo/bar"));
+ plan(13);
+
+ is_string("a", concat("a", END), "concat 1");
+ is_string("ab", concat("a", "b", END), "concat 2");
+ is_string("ab", concat("ab", "", END), "concat 3");
+ is_string("ab", concat("", "ab", END), "concat 4");
+ is_string("", concat("", END), "concat 5");
+ is_string("abcde", concat("ab", "c", "", "de", END), "concat 6");
+ is_string("abcde", concat("abc", "de", END, "f", END), "concat 7");
+
+ is_string("/foo", concatpath("/bar", "/foo"), "path 1");
+ is_string("/foo/bar", concatpath("/foo", "bar"), "path 2");
+ is_string("./bar", concatpath("/foo", "./bar"), "path 3");
+ is_string("/bar/baz/foo/bar", concatpath("/bar/baz", "foo/bar"), "path 4");
+ is_string("./foo", concatpath(NULL, "foo"), "path 5");
+ is_string("/foo/bar", concatpath(NULL, "/foo/bar"), "path 6");
return 0;
}
diff --git a/tests/util/messages-krb5-t.c b/tests/util/messages-krb5-t.c
new file mode 100644
index 0000000..02d8f92
--- /dev/null
+++ b/tests/util/messages-krb5-t.c
@@ -0,0 +1,99 @@
+/*
+ * Test suite for Kerberos error handling routines.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2010 Board of Trustees, Leland Stanford Jr. University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <config.h>
+#include <portable/krb5.h>
+#include <portable/system.h>
+
+#include <tests/tap/basic.h>
+#include <tests/tap/process.h>
+#include <util/messages-krb5.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
+
+
+/*
+ * Test functions.
+ */
+static void
+test_warn(void)
+{
+ krb5_context ctx;
+ krb5_error_code code;
+ krb5_principal princ;
+
+ code = krb5_init_context(&ctx);
+ if (code < 0)
+ die_krb5(ctx, code, "cannot create context");
+ code = krb5_parse_name(ctx, "foo@bar@EXAMPLE.COM", &princ);
+ if (code < 0)
+ warn_krb5(ctx, code, "principal parse failed");
+ else
+ die("unexpected success parsing principal");
+ exit(0);
+}
+
+static void
+test_die(void)
+{
+ krb5_context ctx;
+ krb5_error_code code;
+ krb5_principal princ;
+
+ code = krb5_init_context(&ctx);
+ if (code < 0)
+ die_krb5(ctx, code, "cannot create context");
+ code = krb5_parse_name(ctx, "foo@bar@EXAMPLE.COM", &princ);
+ if (code < 0)
+ die_krb5(ctx, code, "principal parse failed");
+ else
+ die("unexpected success parsing principal");
+ exit(0);
+}
+
+
+/*
+ * Run the tests.
+ */
+int
+main(void)
+{
+ krb5_context ctx;
+ krb5_error_code code;
+ krb5_principal princ;
+ const char *message;
+ char *wanted;
+
+ plan(6 * 3);
+
+ /* First, we have to get what the correct error message is. */
+ code = krb5_init_context(&ctx);
+ if (code < 0)
+ bail("cannot create context");
+ code = krb5_parse_name(ctx, "foo@bar@EXAMPLE.COM", &princ);
+ message = krb5_get_error_message(ctx, code);
+
+ xasprintf(&wanted, "principal parse failed: %s\n", message);
+ is_function_output(test_warn, 0, wanted, "warn_krb5");
+ is_function_output(test_die, 1, wanted, "die_krb5");
+ free(wanted);
+
+ message_program_name = "msg-test";
+ xasprintf(&wanted, "msg-test: principal parse failed: %s\n", message);
+ is_function_output(test_warn, 0, wanted, "warn_krb5 with name");
+ is_function_output(test_die, 1, wanted, "die_krb5 with name");
+ free(wanted);
+
+ message_handlers_warn(0);
+ is_function_output(test_warn, 0, "", "warn_krb5 with no handlers");
+ message_handlers_die(0);
+ is_function_output(test_die, 1, "", "warn_krb5 with no handlers");
+
+ return 0;
+}
diff --git a/tests/util/messages-t.c b/tests/util/messages-t.c
index 434ef56..fb82a42 100644
--- a/tests/util/messages-t.c
+++ b/tests/util/messages-t.c
@@ -1,26 +1,14 @@
-/* $Id$
- *
+/*
* Test suite for error handling routines.
*
- * Copyright 2004, 2005, 2006
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
- * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- * 2003 by The Internet Software Consortium and Rich Salz
- *
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * See LICENSE for licensing terms.
*/
#include <config.h>
@@ -31,67 +19,11 @@
#include <sys/stat.h>
#include <sys/wait.h>
-#include <tests/libtest.h>
-#include <util/util.h>
-
-#define END (char *) 0
-
-/* Test function type. */
-typedef void (*test_function_t)(void);
-
-
-/*
- * Fork and execute the provided function, connecting stdout and stderr to a
- * pipe. Captures the output into the provided buffer and returns the exit
- * status as a waitpid status value.
- */
-static int
-run_test(test_function_t function, char *buf, size_t buflen)
-{
- int fds[2];
- pid_t child;
- ssize_t count, status;
- int rval;
-
- /* Flush stdout before we start to avoid odd forking issues. */
- fflush(stdout);
-
- /* Set up the pipe and call the function, collecting its output. */
- if (pipe(fds) == -1)
- sysdie("can't create pipe");
- child = fork();
- if (child == (pid_t) -1) {
- sysdie("can't fork");
- } else if (child == 0) {
- /* In child. Set up our stdout and stderr. */
- close(fds[0]);
- if (dup2(fds[1], 1) == -1)
- _exit(255);
- if (dup2(fds[1], 2) == -1)
- _exit(255);
-
- /* Now, run the function and exit successfully if it returns. */
- (*function)();
- fflush(stdout);
- _exit(0);
- } else {
- /*
- * In the parent; close the extra file descriptor, read the output if
- * any, and then collect the exit status.
- */
- close(fds[1]);
- count = 0;
- do {
- status = read(fds[0], buf + count, buflen - count - 1);
- if (status > 0)
- count += status;
- } while (status > 0);
- buf[count < 0 ? 0 : count] = '\0';
- if (waitpid(child, &rval, 0) == (pid_t) -1)
- sysdie("waitpid failed");
- }
- return rval;
-}
+#include <tests/tap/basic.h>
+#include <tests/tap/process.h>
+#include <util/concat.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
/*
@@ -204,43 +136,20 @@ static void test24(void) {
/*
- * Given the test number, intended exit status and message, and the function
- * to run, print ok or not ok.
+ * Given the intended status, intended message sans the appended strerror
+ * output, errno, and the function to run, check the output.
*/
static void
-test_error(int n, int status, const char *output, test_function_t function)
+test_strerror(int status, const char *output, int error,
+ test_function_type function)
{
- int real_status;
- char buf[256];
- int succeeded = 1;
-
- real_status = run_test(function, buf, sizeof(buf));
- if (!WIFEXITED(real_status) || status != WEXITSTATUS(real_status)) {
- printf(" unexpected exit status %d\n", real_status);
- succeeded = 0;
- }
- if (strcmp(output, buf)) {
- printf(" unexpected output: %s", buf);
- printf(" expected output: %s", output);
- succeeded = 0;
- }
- printf("%sok %d\n", succeeded ? "" : "not ", n);
-}
+ char *full_output, *name;
-
-/*
- * Given the test number, intended status, intended message sans the appended
- * strerror output, errno, and the function to run, print ok or not ok.
- */
-static void
-test_strerror(int n, int status, const char *output, int error,
- test_function_t function)
-{
- char *full_output;
-
- full_output = concat(output, ": ", strerror(error), "\n", END);
- test_error(n, status, full_output, function);
+ full_output = concat(output, ": ", strerror(error), "\n", (char *) NULL);
+ xasprintf(&name, "strerror %d", testnum / 3 + 1);
+ is_function_output(function, status, full_output, name);
free(full_output);
+ free(name);
}
@@ -251,46 +160,47 @@ int
main(void)
{
char buff[32];
-
- test_init(24);
-
- test_error(1, 0, "warning\n", test1);
- test_error(2, 1, "fatal\n", test2);
- test_strerror(3, 0, "permissions", EPERM, test3);
- test_strerror(4, 1, "fatal access", EACCES, test4);
- test_error(5, 0, "test5: warning\n", test5);
- test_error(6, 1, "test6: fatal\n", test6);
- test_strerror(7, 0, "test7: perms 7", EPERM, test7);
- test_strerror(8, 1, "test8: fatal", EACCES, test8);
- test_error(9, 10, "fatal\n", test9);
- test_strerror(10, 10, "fatal perm", EPERM, test10);
- test_strerror(11, 10, "1st test11: fatal", EPERM, test11);
- test_error(12, 0, "7 0 warning\n", test12);
- test_error(13, 1, "5 0 fatal\n", test13);
+ char *output;
+
+ plan(24 * 3);
+
+ is_function_output(test1, 0, "warning\n", "test1");
+ is_function_output(test2, 1, "fatal\n", "test2");
+ test_strerror(0, "permissions", EPERM, test3);
+ test_strerror(1, "fatal access", EACCES, test4);
+ is_function_output(test5, 0, "test5: warning\n", "test5");
+ is_function_output(test6, 1, "test6: fatal\n", "test6");
+ test_strerror(0, "test7: perms 7", EPERM, test7);
+ test_strerror(1, "test8: fatal", EACCES, test8);
+ is_function_output(test9, 10, "fatal\n", "test9");
+ test_strerror(10, "fatal perm", EPERM, test10);
+ test_strerror(10, "1st test11: fatal", EPERM, test11);
+ is_function_output(test12, 0, "7 0 warning\n", "test12");
+ is_function_output(test13, 1, "5 0 fatal\n", "test13");
sprintf(buff, "%d", EPERM);
- test_error(14, 0,
- concat("7 ", buff, " warning\n7 ", buff, " warning\n", END),
- test14);
- test_error(15, 10,
- concat("5 ", buff, " fatal\n5 ", buff, " fatal\n", END),
- test15);
- test_error(16, 0,
- concat("test16: warning: ", strerror(EPERM), "\n7 ", buff,
- " warning\n", END),
- test16);
-
- test_error(17, 0, "notice\n", test17);
- test_error(18, 0, "test18: notice\n", test18);
- test_error(19, 0, "", test19);
- test_error(20, 0, "3 0 foo\n", test20);
- test_error(21, 0, "test23: baz\n", test21);
+ xasprintf(&output, "7 %d warning\n7 %d warning\n", EPERM, EPERM);
+ is_function_output(test14, 0, output, "test14");
+ free(output);
+ xasprintf(&output, "5 %d fatal\n5 %d fatal\n", EPERM, EPERM);
+ is_function_output(test15, 10, output, "test15");
+ free(output);
+ xasprintf(&output, "test16: warning: %s\n7 %d warning\n", strerror(EPERM),
+ EPERM);
+ is_function_output(test16, 0, output, "test16");
+ free(output);
+
+ is_function_output(test17, 0, "notice\n", "test17");
+ is_function_output(test18, 0, "test18: notice\n", "test18");
+ is_function_output(test19, 0, "", "test19");
+ is_function_output(test20, 0, "3 0 foo\n", "test20");
+ is_function_output(test21, 0, "test23: baz\n", "test21");
/* Make sure that it's possible to turn off a message type entirely. */
- test_error(22, 1, "", test22);
- test_error(23, 0, "", test23);
- test_error(24, 0, "first\nthird\n", test24);
+ is_function_output(test22, 1, "", "test22");
+ is_function_output(test23, 0, "", "test23");
+ is_function_output(test24, 0, "first\nthird\n", "test24");
return 0;
}
diff --git a/tests/util/xmalloc-t b/tests/util/xmalloc-t
new file mode 100755
index 0000000..02f54b5
--- /dev/null
+++ b/tests/util/xmalloc-t
@@ -0,0 +1,127 @@
+#! /bin/sh
+#
+# Test suite for xmalloc and friends.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2008, 2009, 2010 Board of Trustees, Leland Stanford Jr. University
+# Copyright 2004, 2005, 2006
+# by Internet Systems Consortium, Inc. ("ISC")
+# Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003 by The Internet Software Consortium and Rich Salz
+#
+# See LICENSE for licensing terms.
+
+. "$SOURCE/tap/libtap.sh"
+cd "$BUILD/util"
+
+# Run an xmalloc test. Takes the description, the expectd exit status, the
+# output, and the arguments.
+ok_xmalloc () {
+ local desc w_status w_output output status
+ desc="$1"
+ shift
+ w_status="$1"
+ shift
+ w_output="$1"
+ shift
+ output=`./xmalloc "$@" 2>&1`
+ status=$?
+ if [ "$w_status" -ne 0 ] ; then
+ output=`echo "$output" | sed 's/:.*//'`
+ fi
+ if [ $status = $w_status ] && [ x"$output" = x"$w_output" ] ; then
+ ok "$desc" true
+ elif [ $status = 2 ] ; then
+ skip "no data limit support"
+ else
+ echo "# saw: ($status) $output"
+ echo "# not: ($w_status) $w_output"
+ ok "$desc" false
+ fi
+}
+
+# Skip this test suite unless maintainer-mode tests are enabled. All of the
+# failures in automated testing have been problems with the assumptions around
+# memory allocation or problems with the test suite, not problems with the
+# underlying xmalloc code.
+if [ -z "$RRA_MAINTAINER_TESTS" ] ; then
+ skip_all 'xmalloc tests only run for maintainer'
+fi
+
+# Total tests.
+plan 36
+
+# First run the tests expected to succeed.
+ok_xmalloc "malloc small" 0 "" "m" "21" "0"
+ok_xmalloc "malloc large" 0 "" "m" "3500000" "0"
+ok_xmalloc "malloc zero" 0 "" "m" "0" "0"
+ok_xmalloc "realloc small" 0 "" "r" "21" "0"
+ok_xmalloc "realloc large" 0 "" "r" "3500000" "0"
+ok_xmalloc "strdup small" 0 "" "s" "21" "0"
+ok_xmalloc "strdup large" 0 "" "s" "3500000" "0"
+ok_xmalloc "strndup small" 0 "" "n" "21" "0"
+ok_xmalloc "strndup large" 0 "" "n" "3500000" "0"
+ok_xmalloc "calloc small" 0 "" "c" "24" "0"
+ok_xmalloc "calloc large" 0 "" "c" "3500000" "0"
+ok_xmalloc "asprintf small" 0 "" "a" "24" "0"
+ok_xmalloc "asprintf large" 0 "" "a" "3500000" "0"
+ok_xmalloc "vasprintf small" 0 "" "v" "24" "0"
+ok_xmalloc "vasprintf large" 0 "" "v" "3500000" "0"
+
+# Now limit our memory to 3.5MB and then try the large ones again, all of
+# which should fail.
+#
+# The exact memory limits used here are essentially black magic. They need to
+# be large enough to allow the program to be loaded and do small allocations,
+# but not so large that we can't reasonably expect to allocate that much
+# memory normally. 3.5MB seems to work reasonably well on both Solaris and
+# Linux.
+#
+# We assume that there are enough miscellaneous allocations that an allocation
+# exactly as large as the limit will always fail.
+ok_xmalloc "malloc fail" 1 \
+ "failed to malloc 3500000 bytes at xmalloc.c line 38" \
+ "m" "3500000" "3500000"
+ok_xmalloc "realloc fail" 1 \
+ "failed to realloc 3500000 bytes at xmalloc.c line 66" \
+ "r" "3500000" "3500000"
+ok_xmalloc "strdup fail" 1 \
+ "failed to strdup 3500000 bytes at xmalloc.c line 97" \
+ "s" "3500000" "3500000"
+ok_xmalloc "strndup fail" 1 \
+ "failed to strndup 3500000 bytes at xmalloc.c line 124" \
+ "n" "3500000" "3500000"
+ok_xmalloc "calloc fail" 1 \
+ "failed to calloc 3500000 bytes at xmalloc.c line 148" \
+ "c" "3500000" "3500000"
+ok_xmalloc "asprintf fail" 1 \
+ "failed to asprintf 3500000 bytes at xmalloc.c line 173" \
+ "a" "3500000" "3500000"
+ok_xmalloc "vasprintf fail" 1 \
+ "failed to vasprintf 3500000 bytes at xmalloc.c line 193" \
+ "v" "3500000" "3500000"
+
+# Check our custom error handler.
+ok_xmalloc "malloc custom" 1 "malloc 3500000 xmalloc.c 38" \
+ "M" "3500000" "3500000"
+ok_xmalloc "realloc custom" 1 "realloc 3500000 xmalloc.c 66" \
+ "R" "3500000" "3500000"
+ok_xmalloc "strdup custom" 1 "strdup 3500000 xmalloc.c 97" \
+ "S" "3500000" "3500000"
+ok_xmalloc "strndup custom" 1 "strndup 3500000 xmalloc.c 124" \
+ "N" "3500000" "3500000"
+ok_xmalloc "calloc custom" 1 "calloc 3500000 xmalloc.c 148" \
+ "C" "3500000" "3500000"
+ok_xmalloc "asprintf custom" 1 "asprintf 3500000 xmalloc.c 173" \
+ "A" "3500000" "3500000"
+ok_xmalloc "vasprintf custom" 1 "vasprintf 3500000 xmalloc.c 193" \
+ "V" "3500000" "3500000"
+
+# Check the smaller ones again just for grins.
+ok_xmalloc "malloc retry" 0 "" "m" "21" "3500000"
+ok_xmalloc "realloc retry" 0 "" "r" "32" "3500000"
+ok_xmalloc "strdup retry" 0 "" "s" "64" "3500000"
+ok_xmalloc "strndup retry" 0 "" "n" "20" "3500000"
+ok_xmalloc "calloc retry" 0 "" "c" "24" "3500000"
+ok_xmalloc "asprintf retry" 0 "" "a" "30" "3500000"
+ok_xmalloc "vasprintf retry" 0 "" "v" "35" "3500000"
diff --git a/tests/util/xmalloc-t.in b/tests/util/xmalloc-t.in
deleted file mode 100644
index f721822..0000000
--- a/tests/util/xmalloc-t.in
+++ /dev/null
@@ -1,127 +0,0 @@
-#! /bin/sh
-# $Id$
-#
-# Test suite for xmalloc and friends.
-#
-# Copyright 2004, 2005, 2006
-# by Internet Systems Consortium, Inc. ("ISC")
-# Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003 by The Internet Software Consortium and Rich Salz
-#
-# This code is derived from software contributed to the Internet Software
-# Consortium by Rich Salz.
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-# The count starts at 1 and is updated each time ok is printed. printcount
-# takes "ok" or "not ok".
-count=1
-printcount () {
- echo "$1 $count $2"
- count=`expr $count + 1`
-}
-
-# Run a program expected to succeed, and print ok if it does.
-runsuccess () {
- output=`$xmalloc "$1" "$2" "$3" 2>&1 >/dev/null`
- status=$?
- if test $status = 0 && test -z "$output" ; then
- printcount "ok"
- else
- if test $status = 2 ; then
- printcount "ok" "# skip - no data limit support"
- else
- printcount "not ok"
- echo " $output"
- fi
- fi
-}
-
-# Run a program expected to fail and make sure it fails with an exit status
-# of 2 and the right failure message. Strip the colon and everything after
-# it off the error message since it's system-specific.
-runfailure () {
- output=`$xmalloc "$1" "$2" "$3" 2>&1 >/dev/null`
- status=$?
- output=`echo "$output" | sed 's/:.*//' \
- | sed 's% [^ ]*/xmalloc.c% xmalloc.c%'`
- if test $status = 1 && test x"$output" = x"$4" ; then
- printcount "ok"
- else
- if test $status = 2 ; then
- printcount "ok" "# skip - no data limit support"
- else
- printcount "not ok"
- echo " saw: $output"
- echo " not: $4"
- fi
- fi
-}
-
-# Find where the helper program is.
-xmalloc="@abs_top_builddir@/tests/util/xmalloc"
-
-# Total tests.
-echo 36
-
-# First run the tests expected to succeed.
-runsuccess "m" "21" "0"
-runsuccess "m" "128000" "0"
-runsuccess "m" "0" "0"
-runsuccess "r" "21" "0"
-runsuccess "r" "128000" "0"
-runsuccess "s" "21" "0"
-runsuccess "s" "128000" "0"
-runsuccess "n" "21" "0"
-runsuccess "n" "128000" "0"
-runsuccess "c" "24" "0"
-runsuccess "c" "128000" "0"
-runsuccess "a" "24" "0"
-runsuccess "a" "128000" "0"
-runsuccess "v" "24" "0"
-runsuccess "v" "128000" "0"
-
-# Now limit our memory to 120KB and then try the large ones again, all of
-# which should fail.
-runfailure "m" "128000" "120000" \
- "failed to malloc 128000 bytes at xmalloc.c line 61"
-runfailure "r" "128000" "120000" \
- "failed to realloc 128000 bytes at xmalloc.c line 90"
-runfailure "s" "64000" "120000" \
- "failed to strdup 64000 bytes at xmalloc.c line 121"
-runfailure "n" "64000" "120000" \
- "failed to strndup 64000 bytes at xmalloc.c line 148"
-runfailure "c" "128000" "120000" \
- "failed to calloc 128000 bytes at xmalloc.c line 172"
-runfailure "a" "64000" "120000" \
- "failed to asprintf 64000 bytes at xmalloc.c line 241"
-runfailure "v" "64000" "120000" \
- "failed to vasprintf 64000 bytes at xmalloc.c line 217"
-
-# Check our custom error handler.
-runfailure "M" "128000" "120000" "malloc 128000 xmalloc.c 61"
-runfailure "R" "128000" "120000" "realloc 128000 xmalloc.c 90"
-runfailure "S" "64000" "120000" "strdup 64000 xmalloc.c 121"
-runfailure "N" "64000" "120000" "strndup 64000 xmalloc.c 148"
-runfailure "C" "128000" "120000" "calloc 128000 xmalloc.c 172"
-runfailure "A" "64000" "120000" "asprintf 64000 xmalloc.c 241"
-runfailure "V" "64000" "120000" "vasprintf 64000 xmalloc.c 217"
-
-# Check the smaller ones again just for grins.
-runsuccess "m" "21" "96000"
-runsuccess "r" "32" "96000"
-runsuccess "s" "64" "96000"
-runsuccess "n" "20" "96000"
-runsuccess "c" "24" "96000"
-runsuccess "a" "30" "96000"
-runsuccess "v" "35" "96000"
diff --git a/tests/util/xmalloc.c b/tests/util/xmalloc.c
index 699d0c4..3bd5588 100644
--- a/tests/util/xmalloc.c
+++ b/tests/util/xmalloc.c
@@ -1,28 +1,17 @@
-/* $Id$
- *
+/*
* Test suite for xmalloc and family.
*
+ * Copyright 2008 Board of Trustees, Leland Stanford Jr. University
* Copyright 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
* Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
* 2003 by The Internet Software Consortium and Rich Salz
*
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * See LICENSE for licensing terms.
*/
+#line 1 "xmalloc.c"
+
#include <config.h>
#include <portable/system.h>
@@ -33,7 +22,8 @@
/* Linux requires sys/time.h be included before sys/resource.h. */
#include <sys/resource.h>
-#include <util/util.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
/*
@@ -82,20 +72,19 @@ test_realloc(size_t size)
char *buffer;
size_t i;
- buffer = xmalloc(size / 2);
+ buffer = xmalloc(10);
if (buffer == NULL)
return 0;
- if (size / 2 > 0)
- memset(buffer, 1, size / 2);
+ memset(buffer, 1, 10);
buffer = xrealloc(buffer, size);
if (buffer == NULL)
return 0;
if (size > 0)
- memset(buffer + size / 2, 2, size - size / 2);
- for (i = 0; i < size / 2; i++)
+ memset(buffer + 10, 2, size - 10);
+ for (i = 0; i < 10; i++)
if (buffer[i] != 1)
return 0;
- for (i = size / 2; i < size; i++)
+ for (i = 10; i < size; i++)
if (buffer[i] != 2)
return 0;
free(buffer);
@@ -258,6 +247,7 @@ main(int argc, char *argv[])
int willfail = 0;
unsigned char code;
struct rlimit rl;
+ void *tmp;
if (argc < 3)
die("Usage error. Type, size, and limit must be given.");
@@ -270,6 +260,27 @@ main(int argc, char *argv[])
if (limit == 0 && errno != 0)
sysdie("Invalid limit");
+ /* If the code is capitalized, install our customized error handler. */
+ code = argv[1][0];
+ if (isupper(code)) {
+ xmalloc_error_handler = test_handler;
+ code = tolower(code);
+ }
+
+ /*
+ * Decide if the allocation should fail. If it should, set willfail to 2,
+ * so that if it unexpectedly succeeds, we exit with a status indicating
+ * that the test should be skipped.
+ */
+ max = size;
+ if (code == 's' || code == 'n' || code == 'a' || code == 'v') {
+ max += size;
+ if (limit > 0)
+ limit += size;
+ }
+ if (limit > 0 && max > limit)
+ willfail = 2;
+
/*
* If a memory limit was given and we can set memory limits, set it.
* Otherwise, exit 2, signalling to the driver that the test should be
@@ -278,37 +289,28 @@ main(int argc, char *argv[])
* the shell to die).
*/
if (limit > 0) {
-#if HAVE_SETRLIMIT && defined(RLIMIT_DATA)
+#if HAVE_SETRLIMIT && defined(RLIMIT_AS)
rl.rlim_cur = limit;
rl.rlim_max = limit;
- if (setrlimit(RLIMIT_DATA, &rl) < 0) {
+ if (setrlimit(RLIMIT_AS, &rl) < 0) {
syswarn("Can't set data limit to %lu", (unsigned long) limit);
exit(2);
}
+ if (size < limit || code == 'r') {
+ tmp = malloc(code == 'r' ? 10 : size);
+ if (tmp == NULL) {
+ syswarn("Can't allocate initial memory of %lu",
+ (unsigned long) size);
+ exit(2);
+ }
+ free(tmp);
+ }
#else
warn("Data limits aren't supported.");
exit(2);
#endif
}
- /* If the code is capitalized, install our customized error handler. */
- code = argv[1][0];
- if (isupper(code)) {
- xmalloc_error_handler = test_handler;
- code = tolower(code);
- }
-
- /*
- * Decide if the allocation should fail. If it should, set willfail to 2,
- * so that if it unexpectedly succeeds, we exit with a status indicating
- * that the test should be skipped.
- */
- max = size;
- if (code == 's' || code == 'n' || code == 'a' || code == 'v')
- max *= 2;
- if (limit > 0 && max > limit)
- willfail = 2;
-
switch (code) {
case 'c': exit(test_calloc(size) ? willfail : 1);
case 'm': exit(test_malloc(size) ? willfail : 1);
diff --git a/util/concat.c b/util/concat.c
index 1d08e08..bdbd836 100644
--- a/util/concat.c
+++ b/util/concat.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Concatenate strings with dynamic memory allocation.
*
* Usage:
@@ -26,7 +25,8 @@
#include <config.h>
#include <portable/system.h>
-#include <util/util.h>
+#include <util/concat.h>
+#include <util/xmalloc.h>
/* Abbreviation for cleaner code. */
#define VA_NEXT(var, type) ((var) = (type) va_arg(args, type))
diff --git a/util/concat.h b/util/concat.h
new file mode 100644
index 0000000..ef8b38d
--- /dev/null
+++ b/util/concat.h
@@ -0,0 +1,36 @@
+/*
+ * Prototypes for string concatenation with dynamic memory allocation.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * This work is hereby placed in the public domain by its author.
+ */
+
+#ifndef UTIL_CONCAT_H
+#define UTIL_CONCAT_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+BEGIN_DECLS
+
+/* Default to a hidden visibility for all util functions. */
+#pragma GCC visibility push(hidden)
+
+/* Concatenate NULL-terminated strings into a newly allocated string. */
+char *concat(const char *first, ...)
+ __attribute__((__malloc__, __nonnull__(1)));
+
+/*
+ * Given a base path and a file name, create a newly allocated path string.
+ * The name will be appended to base with a / between them. Exceptionally, if
+ * name begins with a slash, it will be strdup'd and returned as-is.
+ */
+char *concatpath(const char *base, const char *name)
+ __attribute__((__malloc__, __nonnull__(2)));
+
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
+END_DECLS
+
+#endif /* UTIL_CONCAT_H */
diff --git a/util/macros.h b/util/macros.h
new file mode 100644
index 0000000..97b2c2b
--- /dev/null
+++ b/util/macros.h
@@ -0,0 +1,17 @@
+/*
+ * Some standard helpful macros.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * This work is hereby placed in the public domain by its author.
+ */
+
+#ifndef UTIL_MACROS_H
+#define UTIL_MACROS_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+/* Used for unused parameters to silence gcc warnings. */
+#define UNUSED __attribute__((__unused__))
+
+#endif /* UTIL_MACROS_H */
diff --git a/util/messages-krb5.c b/util/messages-krb5.c
index caf29b9..7f35d29 100644
--- a/util/messages-krb5.c
+++ b/util/messages-krb5.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Error handling for Kerberos v5.
*
* Provides versions of die and warn that take a Kerberos context and a
@@ -7,76 +6,20 @@
* formatted message.
*
* Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2006, 2007, 2008
+ * Copyright 2006, 2007, 2008, 2009, 2010
* Board of Trustees, Leland Stanford Jr. University
*
* See LICENSE for licensing terms.
*/
#include <config.h>
+#include <portable/krb5.h>
#include <portable/system.h>
-#include <krb5.h>
-#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) && !defined(HAVE_KRB5_GET_ERR_TEXT)
-# if defined(HAVE_IBM_SVC_KRB5_SVC_H)
-# include <ibm_svc/krb5_svc.h>
-# elif defined(HAVE_ET_COM_ERR_H)
-# include <et/com_err.h>
-# else
-# include <com_err.h>
-# endif
-#endif
-
-#include <util/util.h>
-
-/*
- * This string is returned for unknown error messages. We use a static
- * variable so that we can be sure not to free it.
- */
-static const char error_unknown[] = "unknown error";
-
-
-/*
- * Given a Kerberos error code, return the corresponding error. Prefer the
- * Kerberos interface if available since it will provide context-specific
- * error information, whereas the error_message() call will only provide a
- * fixed message.
- */
-static const char *
-get_error(krb5_context ctx UNUSED, krb5_error_code code)
-{
- const char *msg = NULL;
-
-#if defined(HAVE_KRB5_GET_ERROR_MESSAGE)
- msg = krb5_get_error_message(ctx, code);
-#elif defined(HAVE_KRB5_GET_ERR_TEXT)
- msg = krb5_get_err_text(ctx, code);
-#elif defined(HAVE_KRB5_SVC_GET_MSG)
- krb5_svc_get_msg(code, &msg);
-#else
- msg = error_message(code);
-#endif
- if (msg == NULL)
- return error_unknown;
- else
- return msg;
-}
-
-
-/*
- * Free an error string if necessary.
- */
-static void
-free_error(krb5_context ctx UNUSED, const char *msg)
-{
- if (msg == error_unknown)
- return;
-#if defined(HAVE_KRB5_FREE_ERROR_MESSAGE)
- krb5_free_error_message(ctx, msg);
-#elif defined(HAVE_KRB5_SVC_GET_MSG)
- krb5_free_string((char *) msg);
-#endif
-}
+#include <util/macros.h>
+#include <util/messages.h>
+#include <util/messages-krb5.h>
+#include <util/xmalloc.h>
/*
@@ -89,7 +32,7 @@ die_krb5(krb5_context ctx, krb5_error_code code, const char *format, ...)
char *message;
va_list args;
- k5_msg = get_error(ctx, code);
+ k5_msg = krb5_get_error_message(ctx, code);
va_start(args, format);
if (xvasprintf(&message, format, args) < 0)
die("internal error: unable to format error message");
@@ -108,12 +51,12 @@ warn_krb5(krb5_context ctx, krb5_error_code code, const char *format, ...)
char *message;
va_list args;
- k5_msg = get_error(ctx, code);
+ k5_msg = krb5_get_error_message(ctx, code);
va_start(args, format);
if (xvasprintf(&message, format, args) < 0)
die("internal error: unable to format error message");
va_end(args);
warn("%s: %s", message, k5_msg);
free(message);
- free_error(ctx, k5_msg);
+ krb5_free_error_message(ctx, k5_msg);
}
diff --git a/util/messages-krb5.h b/util/messages-krb5.h
new file mode 100644
index 0000000..3b763c8
--- /dev/null
+++ b/util/messages-krb5.h
@@ -0,0 +1,39 @@
+/*
+ * Prototypes for error handling for Kerberos.
+ *
+ * Written by Russ Allbery <rra@stanford.edu>
+ * Copyright 2006, 2007, 2008, 2009, 2010
+ * Board of Trustees, Leland Stanford Jr. University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#ifndef UTIL_MESSAGES_KRB5_H
+#define UTIL_MESSAGES_KRB5_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+#include <krb5.h>
+#include <sys/types.h>
+
+BEGIN_DECLS
+
+/* Default to a hidden visibility for all util functions. */
+#pragma GCC visibility push(hidden)
+
+/*
+ * The Kerberos versions of the reporting functions. These take a context and
+ * an error code to get the Kerberos error.
+ */
+void die_krb5(krb5_context, krb5_error_code, const char *, ...)
+ __attribute__((__nonnull__, __noreturn__, __format__(printf, 3, 4)));
+void warn_krb5(krb5_context, krb5_error_code, const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 3, 4)));
+
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
+END_DECLS
+
+#endif /* UTIL_MESSAGES_KRB5_H */
diff --git a/util/messages.c b/util/messages.c
index 7714c2b..ef920b2 100644
--- a/util/messages.c
+++ b/util/messages.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* Message and error reporting (possibly fatal).
*
* Usage:
@@ -52,26 +51,13 @@
* va_list, and the applicable errno value (if any).
*
* Copyright 2008 Board of Trustees, Leland Stanford Jr. University
- * Copyright 2004, 2005, 2006
+ * Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
- * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- * 2003 by The Internet Software Consortium and Rich Salz
- *
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
-*/
+ * See LICENSE for licensing terms.
+ */
#include <config.h>
#include <portable/system.h>
@@ -91,7 +77,9 @@
# define LOG_CRIT EVENTLOG_ERROR_TYPE
#endif
-#include <util/util.h>
+#include <util/macros.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
/* The default handler lists. */
static message_handler_func stdout_handlers[2] = {
@@ -212,7 +200,7 @@ message_log_syslog(int pri, int len, const char *fmt, va_list args, int err)
eventlog = RegisterEventSource(NULL, message_program_name);
if (eventlog != NULL) {
- ReportEvent(eventlog, pri, 0, 0, NULL, 1, 0, &buffer, NULL);
+ ReportEvent(eventlog, (WORD) pri, 0, 0, NULL, 1, 0, &buffer, NULL);
CloseEventLog(eventlog);
}
}
diff --git a/util/messages.h b/util/messages.h
new file mode 100644
index 0000000..ff86f39
--- /dev/null
+++ b/util/messages.h
@@ -0,0 +1,96 @@
+/*
+ * Prototypes for message and error reporting (possibly fatal).
+ *
+ * Copyright 2008, 2010 Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
+ * by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#ifndef UTIL_MESSAGES_H
+#define UTIL_MESSAGES_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+#include <stdarg.h>
+
+BEGIN_DECLS
+
+/* Default to a hidden visibility for all util functions. */
+#pragma GCC visibility push(hidden)
+
+/*
+ * The reporting functions. The ones prefaced by "sys" add a colon, a space,
+ * and the results of strerror(errno) to the output and are intended for
+ * reporting failures of system calls.
+ */
+void debug(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void notice(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void sysnotice(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void warn(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void syswarn(const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 1, 2)));
+void die(const char *, ...)
+ __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2)));
+void sysdie(const char *, ...)
+ __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2)));
+
+/*
+ * Set the handlers for various message functions. All of these functions
+ * take a count of the number of handlers and then function pointers for each
+ * of those handlers. These functions are not thread-safe; they set global
+ * variables.
+ */
+void message_handlers_debug(int count, ...);
+void message_handlers_notice(int count, ...);
+void message_handlers_warn(int count, ...);
+void message_handlers_die(int count, ...);
+
+/*
+ * Some useful handlers, intended to be passed to message_handlers_*. All
+ * handlers take the length of the formatted message, the format, a variadic
+ * argument list, and the errno setting if any.
+ */
+void message_log_stdout(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_stderr(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_debug(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_info(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_notice(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_warning(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_err(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+void message_log_syslog_crit(int, const char *, va_list, int)
+ __attribute((__nonnull__));
+
+/* The type of a message handler. */
+typedef void (*message_handler_func)(int, const char *, va_list, int);
+
+/* If non-NULL, called before exit and its return value passed to exit. */
+extern int (*message_fatal_cleanup)(void);
+
+/*
+ * If non-NULL, prepended (followed by ": ") to all messages printed by either
+ * message_log_stdout or message_log_stderr.
+ */
+extern const char *message_program_name;
+
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
+END_DECLS
+
+#endif /* UTIL_MESSAGES_H */
diff --git a/util/util.h b/util/util.h
deleted file mode 100644
index 0a45c73..0000000
--- a/util/util.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/* $Id$
- *
- * Utility functions.
- *
- * This is a variety of utility functions that are used internally by pieces
- * of remctl. Many of them came originally from INN.
- *
- * Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2005, 2006, 2007, 2008
- * Board of Trustees, Leland Stanford Jr. University
- * Copyright 2004, 2005, 2006, 2007
- * by Internet Systems Consortium, Inc. ("ISC")
- * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- * 2003 by The Internet Software Consortium and Rich Salz
- *
- * See LICENSE for licensing terms.
- */
-
-#ifndef UTIL_UTIL_H
-#define UTIL_UTIL_H 1
-
-#include <config.h>
-#include <portable/macros.h>
-
-#include <krb5.h>
-#include <stdarg.h>
-#include <sys/types.h>
-
-/* Used for unused parameters to silence gcc warnings. */
-#define UNUSED __attribute__((__unused__))
-
-BEGIN_DECLS
-
-/* Concatenate NULL-terminated strings into a newly allocated string. */
-extern char *concat(const char *first, ...);
-
-/*
- * Given a base path and a file name, create a newly allocated path string.
- * The name will be appended to base with a / between them. Exceptionally, if
- * name begins with a slash, it will be strdup'd and returned as-is.
- */
-extern char *concatpath(const char *base, const char *name);
-
-/*
- * The reporting functions. The ones prefaced by "sys" add a colon, a space,
- * and the results of strerror(errno) to the output and are intended for
- * reporting failures of system calls.
- */
-extern void debug(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void notice(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void sysnotice(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void warn(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void syswarn(const char *, ...)
- __attribute__((__format__(printf, 1, 2)));
-extern void die(const char *, ...)
- __attribute__((__noreturn__, __format__(printf, 1, 2)));
-extern void sysdie(const char *, ...)
- __attribute__((__noreturn__, __format__(printf, 1, 2)));
-
-/*
- * The Kerberos versions of the reporting functions. These take a context and
- * an error code to get the Kerberos error.
- */
-void die_krb5(krb5_context, krb5_error_code, const char *, ...)
- __attribute__((__noreturn__, __format__(printf, 3, 4)));
-void warn_krb5(krb5_context, krb5_error_code, const char *, ...)
- __attribute__((__format__(printf, 3, 4)));
-
-/*
- * Set the handlers for various message functions. All of these functions
- * take a count of the number of handlers and then function pointers for each
- * of those handlers. These functions are not thread-safe; they set global
- * variables.
- */
-extern void message_handlers_debug(int count, ...);
-extern void message_handlers_notice(int count, ...);
-extern void message_handlers_warn(int count, ...);
-extern void message_handlers_die(int count, ...);
-
-/*
- * Some useful handlers, intended to be passed to message_handlers_*. All
- * handlers take the length of the formatted message, the format, a variadic
- * argument list, and the errno setting if any.
- */
-extern void message_log_stdout(int, const char *, va_list, int);
-extern void message_log_stderr(int, const char *, va_list, int);
-extern void message_log_syslog_debug(int, const char *, va_list, int);
-extern void message_log_syslog_info(int, const char *, va_list, int);
-extern void message_log_syslog_notice(int, const char *, va_list, int);
-extern void message_log_syslog_warning(int, const char *, va_list, int);
-extern void message_log_syslog_err(int, const char *, va_list, int);
-extern void message_log_syslog_crit(int, const char *, va_list, int);
-
-/* The type of a message handler. */
-typedef void (*message_handler_func)(int, const char *, va_list, int);
-
-/* If non-NULL, called before exit and its return value passed to exit. */
-extern int (*message_fatal_cleanup)(void);
-
-/*
- * If non-NULL, prepended (followed by ": ") to all messages printed by either
- * message_log_stdout or message_log_stderr.
- */
-extern const char *message_program_name;
-
-/*
- * The functions are actually macros so that we can pick up the file and line
- * number information for debugging error messages without the user having to
- * pass those in every time.
- */
-#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__)
-#define xmalloc(size) x_malloc((size), __FILE__, __LINE__)
-#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__)
-#define xstrdup(p) x_strdup((p), __FILE__, __LINE__)
-#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__)
-#define xvasprintf(p, f, a) x_vasprintf((p), (f), (a), __FILE__, __LINE__)
-
-/*
- * asprintf is a special case since it takes variable arguments. If we have
- * support for variadic macros, we can still pass in the file and line and
- * just need to put them somewhere else in the argument list than last.
- * Otherwise, just call x_asprintf directly. This means that the number of
- * arguments x_asprintf takes must vary depending on whether variadic macros
- * are supported.
- */
-#ifdef HAVE_C99_VAMACROS
-# define xasprintf(p, f, ...) \
- x_asprintf((p), __FILE__, __LINE__, (f), __VA_ARGS__)
-#elif HAVE_GNU_VAMACROS
-# define xasprintf(p, f, args...) \
- x_asprintf((p), __FILE__, __LINE__, (f), args)
-#else
-# define xasprintf x_asprintf
-#endif
-
-/*
- * Last two arguments are always file and line number. These are internal
- * implementations that should not be called directly.
- */
-extern void *x_calloc(size_t, size_t, const char *, int);
-extern void *x_malloc(size_t, const char *, int);
-extern void *x_realloc(void *, size_t, const char *, int);
-extern char *x_strdup(const char *, const char *, int);
-extern char *x_strndup(const char *, size_t, const char *, int);
-extern int x_vasprintf(char **, const char *, va_list, const char *, int);
-
-/* asprintf special case. */
-#if HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS
-extern int x_asprintf(char **, const char *, int, const char *, ...);
-#else
-extern int x_asprintf(char **, const char *, ...);
-#endif
-
-/* Failure handler takes the function, the size, the file, and the line. */
-typedef void (*xmalloc_handler_type)(const char *, size_t, const char *, int);
-
-/* The default error handler. */
-void xmalloc_fail(const char *, size_t, const char *, int);
-
-/*
- * Assign to this variable to choose a handler other than the default, which
- * just calls sysdie.
- */
-extern xmalloc_handler_type xmalloc_error_handler;
-
-END_DECLS
-
-#endif /* UTIL_UTIL_H */
diff --git a/util/xmalloc.c b/util/xmalloc.c
index 927372d..4e05f96 100644
--- a/util/xmalloc.c
+++ b/util/xmalloc.c
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
* malloc routines with failure handling.
*
* Usage:
@@ -56,25 +55,12 @@
* header file defines macros named xmalloc, etc. that pass the file name and
* line number to these functions.
*
- * Copyright 2004, 2005, 2006
+ * Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
- * Copyright 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- * 2003 by The Internet Software Consortium and Rich Salz
- *
- * This code is derived from software contributed to the Internet Software
- * Consortium by Rich Salz.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
*
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * See LICENSE for licensing terms.
*/
#include <config.h>
@@ -82,7 +68,8 @@
#include <errno.h>
-#include <util/util.h>
+#include <util/messages.h>
+#include <util/xmalloc.h>
/*
diff --git a/util/xmalloc.h b/util/xmalloc.h
new file mode 100644
index 0000000..657a6bb
--- /dev/null
+++ b/util/xmalloc.h
@@ -0,0 +1,100 @@
+/*
+ * Prototypes for malloc routines with failure handling.
+ *
+ * Copyright 2010 Board of Trustees, Leland Stanford Jr. University
+ * Copyright (c) 2004, 2005, 2006
+ * by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#ifndef UTIL_XMALLOC_H
+#define UTIL_XMALLOC_H 1
+
+#include <config.h>
+#include <portable/macros.h>
+
+#include <sys/types.h>
+
+/*
+ * The functions are actually macros so that we can pick up the file and line
+ * number information for debugging error messages without the user having to
+ * pass those in every time.
+ */
+#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__)
+#define xmalloc(size) x_malloc((size), __FILE__, __LINE__)
+#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__)
+#define xstrdup(p) x_strdup((p), __FILE__, __LINE__)
+#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__)
+#define xvasprintf(p, f, a) x_vasprintf((p), (f), (a), __FILE__, __LINE__)
+
+/*
+ * asprintf is a special case since it takes variable arguments. If we have
+ * support for variadic macros, we can still pass in the file and line and
+ * just need to put them somewhere else in the argument list than last.
+ * Otherwise, just call x_asprintf directly. This means that the number of
+ * arguments x_asprintf takes must vary depending on whether variadic macros
+ * are supported.
+ */
+#ifdef HAVE_C99_VAMACROS
+# define xasprintf(p, f, ...) \
+ x_asprintf((p), __FILE__, __LINE__, (f), __VA_ARGS__)
+#elif HAVE_GNU_VAMACROS
+# define xasprintf(p, f, args...) \
+ x_asprintf((p), __FILE__, __LINE__, (f), args)
+#else
+# define xasprintf x_asprintf
+#endif
+
+BEGIN_DECLS
+
+/* Default to a hidden visibility for all util functions. */
+#pragma GCC visibility push(hidden)
+
+/*
+ * Last two arguments are always file and line number. These are internal
+ * implementations that should not be called directly.
+ */
+void *x_calloc(size_t, size_t, const char *, int)
+ __attribute__((__alloc_size__(1, 2), __malloc__, __nonnull__));
+void *x_malloc(size_t, const char *, int)
+ __attribute__((__alloc_size__(1), __malloc__, __nonnull__));
+void *x_realloc(void *, size_t, const char *, int)
+ __attribute__((__alloc_size__(2), __malloc__, __nonnull__(3)));
+char *x_strdup(const char *, const char *, int)
+ __attribute__((__malloc__, __nonnull__));
+char *x_strndup(const char *, size_t, const char *, int)
+ __attribute__((__malloc__, __nonnull__));
+int x_vasprintf(char **, const char *, va_list, const char *, int)
+ __attribute__((__nonnull__));
+
+/* asprintf special case. */
+#if HAVE_C99_VAMACROS || HAVE_GNU_VAMACROS
+int x_asprintf(char **, const char *, int, const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 4, 5)));
+#else
+int x_asprintf(char **, const char *, ...)
+ __attribute__((__nonnull__, __format__(printf, 2, 3)));
+#endif
+
+/* Failure handler takes the function, the size, the file, and the line. */
+typedef void (*xmalloc_handler_type)(const char *, size_t, const char *, int);
+
+/* The default error handler. */
+void xmalloc_fail(const char *, size_t, const char *, int)
+ __attribute__((__nonnull__));
+
+/*
+ * Assign to this variable to choose a handler other than the default, which
+ * just calls sysdie.
+ */
+extern xmalloc_handler_type xmalloc_error_handler;
+
+/* Undo default visibility change. */
+#pragma GCC visibility pop
+
+END_DECLS
+
+#endif /* UTIL_XMALLOC_H */