diff options
75 files changed, 3224 insertions, 979 deletions
@@ -2,6 +2,7 @@ /aclocal.m4 /build-aux/ /client/wallet +/client/wallet-rekey /config.h /config.h.in /config.h.in~ @@ -19,6 +20,7 @@ /tests/client/basic-t /tests/client/full-t /tests/client/prompt-t +/tests/client/rekey-t /tests/data/.placeholder /tests/data/test.keytab /tests/data/test.password diff --git a/Makefile.am b/Makefile.am index d5dccd9..444df0b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -10,40 +10,43 @@ # 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_FILES = perl/Wallet/ACL.pm perl/Wallet/ACL/Base.pm \ + perl/Wallet/ACL/Krb5.pm perl/Wallet/ACL/Krb5/Regex.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 \ +EXTRA_DIST = .gitignore LICENSE autogen client/wallet.pod \ + client/wallet-rekey.pod config/allow-extract config/keytab \ + config/keytab.acl config/wallet config/wallet-report.acl docs/design \ + contrib/README contrib/convert-srvtab-db contrib/used-principals \ + contrib/wallet-contacts contrib/wallet-summary \ + contrib/wallet-summary.8 contrib/wallet-unknown-hosts \ + 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-foreign \ + tests/data/fake-keytab-merge tests/data/fake-keytab-old \ + tests/data/fake-keytab-partial tests/data/fake-keytab-partial-result \ + tests/data/fake-keytab-rekey tests/data/fake-keytab-unknown \ + 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 @@ -57,23 +60,35 @@ util_libutil_a_SOURCES = util/concat.c util/concat.h util/macros.h \ util/messages.h util/xmalloc.c util/xmalloc.h util_libutil_a_CPPFLAGS = $(KRB5_CPPFLAGS) -bin_PROGRAMS = client/wallet +noinst_LIBRARIES += client/libwallet.a +client_libwallet_a_SOURCES = client/file.c client/internal.h client/keytab.c \ + client/krb5.c client/options.c client/remctl.c client/srvtab.c +client_libwallet_a_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS) + +bin_PROGRAMS = client/wallet client/wallet-rekey 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 \ +client_wallet_LDADD = client/libwallet.a util/libutil.a \ + portable/libportable.a $(REMCTL_LIBS) $(KRB5_LIBS) +client_wallet_rekey_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS) +client_wallet_rekey_LDFLAGS = $(REMCTL_LDFLAGS) $(KRB5_LDFLAGS) +client_wallet_rekey_LDADD = client/libwallet.a util/libutil.a \ + portable/libportable.a $(REMCTL_LIBS) $(KRB5_LIBS) + +dist_man_MANS = client/wallet.1 client/wallet-rekey.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 \ +# without optimization turned on. Desirable warnings that can't be turned +# on due to other problems: +# +# -Wconversion http://bugs.debian.org/488884 (htons warnings) +# +# Last checked against gcc 4.4 (2010-08-15). +WARNINGS = -g -O -Wall -Wextra -Wendif-labels -Wformat=2 -Winit-self \ + -Wswitch-enum -Wdeclaration-after-statement -Wshadow -Wpointer-arith \ -Wbad-function-cast -Wwrite-strings -Wstrict-prototypes \ -Wmissing-prototypes -Wnested-externs -Werror @@ -97,9 +112,9 @@ 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 ; \ + mkdir perl/Wallet perl/Wallet/ACL perl/Wallet/ACL/Krb5 \ + 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 \ diff --git a/Makefile.in b/Makefile.in index c08f7fa..5e2331f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -42,7 +42,7 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -bin_PROGRAMS = client/wallet$(EXEEXT) +bin_PROGRAMS = client/wallet$(EXEEXT) client/wallet-rekey$(EXEEXT) check_PROGRAMS = tests/runtests$(EXEEXT) \ tests/portable/asprintf-t$(EXEEXT) \ tests/portable/mkstemp-t$(EXEEXT) \ @@ -59,7 +59,8 @@ DIST_COMMON = README $(am__configure_deps) $(dist_man_MANS) \ $(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 \ + $(top_srcdir)/tests/client/prompt-t.in \ + $(top_srcdir)/tests/client/rekey-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 \ @@ -77,7 +78,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ 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 + tests/client/full-t tests/client/prompt-t tests/client/rekey-t CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar @@ -88,10 +89,20 @@ 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 = @ +client_libwallet_a_AR = $(AR) $(ARFLAGS) +client_libwallet_a_LIBADD = +am__dirstamp = $(am__leading_dot)dirstamp +am_client_libwallet_a_OBJECTS = \ + client/client_libwallet_a-file.$(OBJEXT) \ + client/client_libwallet_a-keytab.$(OBJEXT) \ + client/client_libwallet_a-krb5.$(OBJEXT) \ + client/client_libwallet_a-options.$(OBJEXT) \ + client/client_libwallet_a-remctl.$(OBJEXT) \ + client/client_libwallet_a-srvtab.$(OBJEXT) +client_libwallet_a_OBJECTS = $(am_client_libwallet_a_OBJECTS) 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) @@ -114,18 +125,22 @@ 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) +client_wallet_SOURCES = client/wallet.c +client_wallet_OBJECTS = client/client_wallet-wallet.$(OBJEXT) am__DEPENDENCIES_1 = -client_wallet_DEPENDENCIES = util/libutil.a portable/libportable.a \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +client_wallet_DEPENDENCIES = client/libwallet.a util/libutil.a \ + portable/libportable.a $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) client_wallet_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(client_wallet_LDFLAGS) $(LDFLAGS) -o $@ +client_wallet_rekey_SOURCES = client/wallet-rekey.c +client_wallet_rekey_OBJECTS = \ + client/client_wallet_rekey-wallet-rekey.$(OBJEXT) +client_wallet_rekey_DEPENDENCIES = client/libwallet.a util/libutil.a \ + portable/libportable.a $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +client_wallet_rekey_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(client_wallet_rekey_LDFLAGS) $(LDFLAGS) -o $@ am_tests_portable_asprintf_t_OBJECTS = \ tests/portable/asprintf-t.$(OBJEXT) \ tests/portable/asprintf.$(OBJEXT) @@ -231,9 +246,11 @@ 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) \ +SOURCES = $(client_libwallet_a_SOURCES) \ + $(portable_libportable_a_SOURCES) \ $(tests_tap_libtap_a_SOURCES) $(util_libutil_a_SOURCES) \ - $(client_wallet_SOURCES) $(tests_portable_asprintf_t_SOURCES) \ + client/wallet.c client/wallet-rekey.c \ + $(tests_portable_asprintf_t_SOURCES) \ $(tests_portable_mkstemp_t_SOURCES) \ $(tests_portable_setenv_t_SOURCES) \ $(tests_portable_snprintf_t_SOURCES) \ @@ -241,9 +258,11 @@ SOURCES = $(portable_libportable_a_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) \ +DIST_SOURCES = $(client_libwallet_a_SOURCES) \ + $(portable_libportable_a_SOURCES) \ $(tests_tap_libtap_a_SOURCES) $(util_libutil_a_SOURCES) \ - $(client_wallet_SOURCES) $(tests_portable_asprintf_t_SOURCES) \ + client/wallet.c client/wallet-rekey.c \ + $(tests_portable_asprintf_t_SOURCES) \ $(tests_portable_mkstemp_t_SOURCES) \ $(tests_portable_setenv_t_SOURCES) \ $(tests_portable_snprintf_t_SOURCES) \ @@ -373,43 +392,47 @@ top_srcdir = @top_srcdir@ # 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_FILES = perl/Wallet/ACL.pm perl/Wallet/ACL/Base.pm \ + perl/Wallet/ACL/Krb5.pm perl/Wallet/ACL/Krb5/Regex.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 \ +EXTRA_DIST = .gitignore LICENSE autogen client/wallet.pod \ + client/wallet-rekey.pod config/allow-extract config/keytab \ + config/keytab.acl config/wallet config/wallet-report.acl docs/design \ + contrib/README contrib/convert-srvtab-db contrib/used-principals \ + contrib/wallet-contacts contrib/wallet-summary \ + contrib/wallet-summary.8 contrib/wallet-unknown-hosts \ + 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-foreign \ + tests/data/fake-keytab-merge tests/data/fake-keytab-old \ + tests/data/fake-keytab-partial tests/data/fake-keytab-partial-result \ + tests/data/fake-keytab-rekey tests/data/fake-keytab-unknown \ + 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 +noinst_LIBRARIES = portable/libportable.a util/libutil.a \ + client/libwallet.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 @@ -421,25 +444,36 @@ util_libutil_a_SOURCES = util/concat.c util/concat.h util/macros.h \ util/messages.h util/xmalloc.c util/xmalloc.h util_libutil_a_CPPFLAGS = $(KRB5_CPPFLAGS) +client_libwallet_a_SOURCES = client/file.c client/internal.h client/keytab.c \ + client/krb5.c client/options.c client/remctl.c client/srvtab.c + +client_libwallet_a_CPPFLAGS = $(REMCTL_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) +client_wallet_LDADD = client/libwallet.a util/libutil.a \ + portable/libportable.a $(REMCTL_LIBS) $(KRB5_LIBS) -dist_man_MANS = client/wallet.1 server/keytab-backend.8 \ +client_wallet_rekey_CPPFLAGS = $(REMCTL_CPPFLAGS) $(KRB5_CPPFLAGS) +client_wallet_rekey_LDFLAGS = $(REMCTL_LDFLAGS) $(KRB5_LDFLAGS) +client_wallet_rekey_LDADD = client/libwallet.a util/libutil.a \ + portable/libportable.a $(REMCTL_LIBS) $(KRB5_LIBS) + +dist_man_MANS = client/wallet.1 client/wallet-rekey.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 \ +# without optimization turned on. Desirable warnings that can't be turned +# on due to other problems: +# +# -Wconversion http://bugs.debian.org/488884 (htons warnings) +# +# Last checked against gcc 4.4 (2010-08-15). +WARNINGS = -g -O -Wall -Wextra -Wendif-labels -Wformat=2 -Winit-self \ + -Wswitch-enum -Wdeclaration-after-statement -Wshadow -Wpointer-arith \ -Wbad-function-cast -Wwrite-strings -Wstrict-prototypes \ -Wmissing-prototypes -Wnested-externs -Werror @@ -563,12 +597,36 @@ tests/client/full-t: $(top_builddir)/config.status $(top_srcdir)/tests/client/fu 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 $@ +tests/client/rekey-t: $(top_builddir)/config.status $(top_srcdir)/tests/client/rekey-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) +client/$(am__dirstamp): + @$(MKDIR_P) client + @: > client/$(am__dirstamp) +client/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) client/$(DEPDIR) + @: > client/$(DEPDIR)/$(am__dirstamp) +client/client_libwallet_a-file.$(OBJEXT): client/$(am__dirstamp) \ + client/$(DEPDIR)/$(am__dirstamp) +client/client_libwallet_a-keytab.$(OBJEXT): client/$(am__dirstamp) \ + client/$(DEPDIR)/$(am__dirstamp) +client/client_libwallet_a-krb5.$(OBJEXT): client/$(am__dirstamp) \ + client/$(DEPDIR)/$(am__dirstamp) +client/client_libwallet_a-options.$(OBJEXT): client/$(am__dirstamp) \ + client/$(DEPDIR)/$(am__dirstamp) +client/client_libwallet_a-remctl.$(OBJEXT): client/$(am__dirstamp) \ + client/$(DEPDIR)/$(am__dirstamp) +client/client_libwallet_a-srvtab.$(OBJEXT): client/$(am__dirstamp) \ + client/$(DEPDIR)/$(am__dirstamp) +client/libwallet.a: $(client_libwallet_a_OBJECTS) $(client_libwallet_a_DEPENDENCIES) client/$(am__dirstamp) + $(AM_V_at)-rm -f client/libwallet.a + $(AM_V_AR)$(client_libwallet_a_AR) client/libwallet.a $(client_libwallet_a_OBJECTS) $(client_libwallet_a_LIBADD) + $(AM_V_at)$(RANLIB) client/libwallet.a portable/$(am__dirstamp): @$(MKDIR_P) portable @: > portable/$(am__dirstamp) @@ -659,27 +717,16 @@ clean-binPROGRAMS: 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) +client/client_wallet_rekey-wallet-rekey.$(OBJEXT): \ + client/$(am__dirstamp) client/$(DEPDIR)/$(am__dirstamp) +client/wallet-rekey$(EXEEXT): $(client_wallet_rekey_OBJECTS) $(client_wallet_rekey_DEPENDENCIES) client/$(am__dirstamp) + @rm -f client/wallet-rekey$(EXEEXT) + $(AM_V_CCLD)$(client_wallet_rekey_LINK) $(client_wallet_rekey_OBJECTS) $(client_wallet_rekey_LDADD) $(LIBS) tests/portable/$(am__dirstamp): @$(MKDIR_P) tests/portable @: > tests/portable/$(am__dirstamp) @@ -803,12 +850,14 @@ uninstall-dist_sbinSCRIPTS: 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_libwallet_a-file.$(OBJEXT) + -rm -f client/client_libwallet_a-keytab.$(OBJEXT) + -rm -f client/client_libwallet_a-krb5.$(OBJEXT) + -rm -f client/client_libwallet_a-options.$(OBJEXT) + -rm -f client/client_libwallet_a-remctl.$(OBJEXT) + -rm -f client/client_libwallet_a-srvtab.$(OBJEXT) -rm -f client/client_wallet-wallet.$(OBJEXT) + -rm -f client/client_wallet_rekey-wallet-rekey.$(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) @@ -840,12 +889,14 @@ mostlyclean-compile: 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_libwallet_a-file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_libwallet_a-keytab.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_libwallet_a-krb5.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_libwallet_a-options.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_libwallet_a-remctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_libwallet_a-srvtab.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_wallet-wallet.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@client/$(DEPDIR)/client_wallet_rekey-wallet-rekey.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@ @@ -898,6 +949,102 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +client/client_libwallet_a-file.o: client/file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-file.o -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-file.Tpo -c -o client/client_libwallet_a-file.o `test -f 'client/file.c' || echo '$(srcdir)/'`client/file.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_libwallet_a-file.Tpo client/$(DEPDIR)/client_libwallet_a-file.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/file.c' object='client/client_libwallet_a-file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-file.o `test -f 'client/file.c' || echo '$(srcdir)/'`client/file.c + +client/client_libwallet_a-file.obj: client/file.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-file.obj -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-file.Tpo -c -o client/client_libwallet_a-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_libwallet_a-file.Tpo client/$(DEPDIR)/client_libwallet_a-file.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/file.c' object='client/client_libwallet_a-file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-file.obj `if test -f 'client/file.c'; then $(CYGPATH_W) 'client/file.c'; else $(CYGPATH_W) '$(srcdir)/client/file.c'; fi` + +client/client_libwallet_a-keytab.o: client/keytab.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-keytab.o -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-keytab.Tpo -c -o client/client_libwallet_a-keytab.o `test -f 'client/keytab.c' || echo '$(srcdir)/'`client/keytab.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_libwallet_a-keytab.Tpo client/$(DEPDIR)/client_libwallet_a-keytab.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/keytab.c' object='client/client_libwallet_a-keytab.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-keytab.o `test -f 'client/keytab.c' || echo '$(srcdir)/'`client/keytab.c + +client/client_libwallet_a-keytab.obj: client/keytab.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-keytab.obj -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-keytab.Tpo -c -o client/client_libwallet_a-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_libwallet_a-keytab.Tpo client/$(DEPDIR)/client_libwallet_a-keytab.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/keytab.c' object='client/client_libwallet_a-keytab.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-keytab.obj `if test -f 'client/keytab.c'; then $(CYGPATH_W) 'client/keytab.c'; else $(CYGPATH_W) '$(srcdir)/client/keytab.c'; fi` + +client/client_libwallet_a-krb5.o: client/krb5.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-krb5.o -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-krb5.Tpo -c -o client/client_libwallet_a-krb5.o `test -f 'client/krb5.c' || echo '$(srcdir)/'`client/krb5.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_libwallet_a-krb5.Tpo client/$(DEPDIR)/client_libwallet_a-krb5.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/krb5.c' object='client/client_libwallet_a-krb5.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-krb5.o `test -f 'client/krb5.c' || echo '$(srcdir)/'`client/krb5.c + +client/client_libwallet_a-krb5.obj: client/krb5.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-krb5.obj -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-krb5.Tpo -c -o client/client_libwallet_a-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_libwallet_a-krb5.Tpo client/$(DEPDIR)/client_libwallet_a-krb5.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/krb5.c' object='client/client_libwallet_a-krb5.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-krb5.obj `if test -f 'client/krb5.c'; then $(CYGPATH_W) 'client/krb5.c'; else $(CYGPATH_W) '$(srcdir)/client/krb5.c'; fi` + +client/client_libwallet_a-options.o: client/options.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-options.o -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-options.Tpo -c -o client/client_libwallet_a-options.o `test -f 'client/options.c' || echo '$(srcdir)/'`client/options.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_libwallet_a-options.Tpo client/$(DEPDIR)/client_libwallet_a-options.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/options.c' object='client/client_libwallet_a-options.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-options.o `test -f 'client/options.c' || echo '$(srcdir)/'`client/options.c + +client/client_libwallet_a-options.obj: client/options.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-options.obj -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-options.Tpo -c -o client/client_libwallet_a-options.obj `if test -f 'client/options.c'; then $(CYGPATH_W) 'client/options.c'; else $(CYGPATH_W) '$(srcdir)/client/options.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_libwallet_a-options.Tpo client/$(DEPDIR)/client_libwallet_a-options.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/options.c' object='client/client_libwallet_a-options.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-options.obj `if test -f 'client/options.c'; then $(CYGPATH_W) 'client/options.c'; else $(CYGPATH_W) '$(srcdir)/client/options.c'; fi` + +client/client_libwallet_a-remctl.o: client/remctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-remctl.o -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-remctl.Tpo -c -o client/client_libwallet_a-remctl.o `test -f 'client/remctl.c' || echo '$(srcdir)/'`client/remctl.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_libwallet_a-remctl.Tpo client/$(DEPDIR)/client_libwallet_a-remctl.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/remctl.c' object='client/client_libwallet_a-remctl.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-remctl.o `test -f 'client/remctl.c' || echo '$(srcdir)/'`client/remctl.c + +client/client_libwallet_a-remctl.obj: client/remctl.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-remctl.obj -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-remctl.Tpo -c -o client/client_libwallet_a-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_libwallet_a-remctl.Tpo client/$(DEPDIR)/client_libwallet_a-remctl.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/remctl.c' object='client/client_libwallet_a-remctl.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-remctl.obj `if test -f 'client/remctl.c'; then $(CYGPATH_W) 'client/remctl.c'; else $(CYGPATH_W) '$(srcdir)/client/remctl.c'; fi` + +client/client_libwallet_a-srvtab.o: client/srvtab.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-srvtab.o -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-srvtab.Tpo -c -o client/client_libwallet_a-srvtab.o `test -f 'client/srvtab.c' || echo '$(srcdir)/'`client/srvtab.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_libwallet_a-srvtab.Tpo client/$(DEPDIR)/client_libwallet_a-srvtab.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/srvtab.c' object='client/client_libwallet_a-srvtab.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-srvtab.o `test -f 'client/srvtab.c' || echo '$(srcdir)/'`client/srvtab.c + +client/client_libwallet_a-srvtab.obj: client/srvtab.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_libwallet_a-srvtab.obj -MD -MP -MF client/$(DEPDIR)/client_libwallet_a-srvtab.Tpo -c -o client/client_libwallet_a-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_libwallet_a-srvtab.Tpo client/$(DEPDIR)/client_libwallet_a-srvtab.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/srvtab.c' object='client/client_libwallet_a-srvtab.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_libwallet_a_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_libwallet_a-srvtab.obj `if test -f 'client/srvtab.c'; then $(CYGPATH_W) 'client/srvtab.c'; else $(CYGPATH_W) '$(srcdir)/client/srvtab.c'; fi` + 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 @@ -1058,86 +1205,6 @@ util/util_libutil_a-xmalloc.obj: util/xmalloc.c @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 @@ -1154,6 +1221,22 @@ client/client_wallet-wallet.obj: client/wallet.c @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` +client/client_wallet_rekey-wallet-rekey.o: client/wallet-rekey.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_rekey_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet_rekey-wallet-rekey.o -MD -MP -MF client/$(DEPDIR)/client_wallet_rekey-wallet-rekey.Tpo -c -o client/client_wallet_rekey-wallet-rekey.o `test -f 'client/wallet-rekey.c' || echo '$(srcdir)/'`client/wallet-rekey.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet_rekey-wallet-rekey.Tpo client/$(DEPDIR)/client_wallet_rekey-wallet-rekey.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/wallet-rekey.c' object='client/client_wallet_rekey-wallet-rekey.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_rekey_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet_rekey-wallet-rekey.o `test -f 'client/wallet-rekey.c' || echo '$(srcdir)/'`client/wallet-rekey.c + +client/client_wallet_rekey-wallet-rekey.obj: client/wallet-rekey.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_rekey_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client/client_wallet_rekey-wallet-rekey.obj -MD -MP -MF client/$(DEPDIR)/client_wallet_rekey-wallet-rekey.Tpo -c -o client/client_wallet_rekey-wallet-rekey.obj `if test -f 'client/wallet-rekey.c'; then $(CYGPATH_W) 'client/wallet-rekey.c'; else $(CYGPATH_W) '$(srcdir)/client/wallet-rekey.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) client/$(DEPDIR)/client_wallet_rekey-wallet-rekey.Tpo client/$(DEPDIR)/client_wallet_rekey-wallet-rekey.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='client/wallet-rekey.c' object='client/client_wallet_rekey-wallet-rekey.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(client_wallet_rekey_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client/client_wallet_rekey-wallet-rekey.obj `if test -f 'client/wallet-rekey.c'; then $(CYGPATH_W) 'client/wallet-rekey.c'; else $(CYGPATH_W) '$(srcdir)/client/wallet-rekey.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 @@ -1634,9 +1717,9 @@ 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 ; \ + mkdir perl/Wallet perl/Wallet/ACL perl/Wallet/ACL/Krb5 \ + 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 \ @@ -1,5 +1,42 @@ User-Visible wallet Changes +wallet 0.12 (2010-08-25) + + New client program wallet-rekey that, given a list of keytabs on the + command line, requests new keytab objects for each principal in the + local realm and then merges the new objects into that keytab. The + current implementation only acquires new keys and doesn't purge any + old keys. + + A new ACL type, krb5-regex, is now supported. This ACL type is the + same as krb5 except that the identifier is interpreted as a Perl + regular expression and matched against the authenticated identity + attempting to run a wallet command. Patch from Ian Durkacz. + + Add a objects unused report to wallet-report and Wallet::Report, + returning all objects that have never been downloaded (in other words, + have never been the target of a get command). + + Add an acls duplicate report to wallet-report and Wallet::Report, + returning sets of ACLs that have exactly the same entries. + + Add a help command to wallet-report, which returns a summary of all + available commands. + + Update to C TAP Harness 1.5: + + * Better reporting of fatal errors in the test suite. + * Summarize results at the end of test execution. + * Add tests/HOWTO from docs/writing-tests in C TAP Harness. + + Update to rra-c-util 2.6: + + * Fix portability to bundled Heimdal on OpenBSD. + * Improve checking for krb5_kt_free_entry with older MIT Kerberos. + * Fix portability for missing krb5_get_init_creds_opt_free. + * Fix header guard for util/xwrite.h. + * Restore default compiler configuration after GSS-API library probe. + wallet 0.11 (2010-03-08) When deleting an ACL on the server, verify that the ACL is not @@ -1,4 +1,4 @@ - wallet release 0.11 + wallet release 0.12 (secure data management system) Written by Russ Allbery <rra@stanford.edu> @@ -8,9 +8,6 @@ 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. - BLURB The wallet is a system for managing secure data, authorization rules to @@ -275,4 +272,5 @@ THANKS security models. To Jon Robertson for the refactoring of Wallet::Kadmin, Heimdal support, - and many of the wallet server-side reports. + many of the wallet server-side reports, and the initial wallet-rekey + implementation. @@ -18,11 +18,6 @@ Client: * Add readline support to the wallet client to make it easier to issue multiple commands. - * 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. - * Support authenticating with a keytab. * Allow store data to contain nuls. Requires rewriting the command @@ -87,6 +82,9 @@ ACLs: * Provide an API for verifiers to syntax-check the values before an ACL is set and implement syntax checking for the Krb5 verifier. + * Investigate how best to support client authentication using anonymous + PKINIT for things like initial system keying. + Database: * Fix case-insensitivity bug in unique keys with MySQL for objects. @@ -130,6 +128,19 @@ Objects: Reports: + * Add audit for references to unknown ACLs, possibly introduced by + previous versions before ACL deletion was checked with database + backends that don't do referential integrity. + + * Add report for all objects that have never been stored. + + * Add report of all ACLs with identical contents. + + * For objects tied to hostnames, report on objects referring to hosts + which do not exist. For the initial pass, this is probably only keytab + objects with names containing a slash where the part after the slash + looks like a hostname. This may need some configuration help. + * Make contrib/wallet-summary generic and include it in wallet-report, with additional configuration in Wallet::Config. Enhance it to report on any sort of object, not just on keytabs, and to give numbers on @@ -13,14 +13,14 @@ 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. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],, +[m4_warning([this file was generated for autoconf 2.67. 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. +# longlong.m4 serial 14 +dnl Copyright (C) 1999-2007, 2009-2010 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. @@ -41,33 +41,33 @@ AC_DEFUN([AC_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])], + 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, + AC_DEFINE([HAVE_LONG_LONG_INT], [1], [Define to 1 if the system has the type `long long int'.]) fi ]) @@ -90,7 +90,7 @@ AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], [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, + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], [Define to 1 if the system has the type `unsigned long long int'.]) fi ]) @@ -103,30 +103,27 @@ AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], 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 + [[/* For now, do not test the preprocessor; as of 2007 there are too many + implementations with broken preprocessors. Perhaps this can + be revisited in 2012. In the meantime, code should not expect + #if to work with literals wider than 32 bits. */ /* 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)]; + ? 1 : -1)]; typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 - ? 1 : -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));]]) + | (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. @@ -11,6 +11,8 @@ rm -rf autom4te.cache 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 client/wallet-rekey.pod \ + > client/wallet-rekey.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 \ diff --git a/client/file.c b/client/file.c index 66d5f63..861da6a 100644 --- a/client/file.c +++ b/client/file.c @@ -48,6 +48,31 @@ overwrite_file(const char *name, const void *data, size_t length) /* + * Given a filename, some data, and a length, append that data to an existing + * file. Dies on any failure. + */ +void +append_file(const char *name, const void *data, size_t length) +{ + int fd; + ssize_t status; + + fd = open(name, O_WRONLY | O_APPEND); + if (fd < 0) + sysdie("open of %s failed", name); + if (length > 0) { + status = write(fd, data, length); + if (status < 0) + sysdie("write to %s failed", name); + else if (status != (ssize_t) length) + die("write to %s truncated", name); + } + if (close(fd) < 0) + sysdie("close of %s failed (file probably truncated)", name); +} + + +/* * Given a filename, some data, and a length, write that data to the given * file safely and atomically by creating file.new, writing the data, linking * file to file.bak, and then renaming file.new to file. diff --git a/client/internal.h b/client/internal.h index d82196c..c8e5802 100644 --- a/client/internal.h +++ b/client/internal.h @@ -15,13 +15,43 @@ #include <sys/types.h> +/* + * Allow defaults to be set for a particular site with configure options if + * people don't want to use krb5.conf for some reason. + */ +#ifndef WALLET_SERVER +# define WALLET_SERVER NULL +#endif +#ifndef WALLET_PORT +# define WALLET_PORT 0 +#endif + /* Forward declarations to avoid unnecessary includes. */ struct remctl; struct iovec; +/* + * Basic wallet behavior options set either on the command line or via + * krb5.conf. If set via krb5.conf, we allocate memory for the strings, but + * we never free them. + */ +struct options { + char *type; + char *server; + char *principal; + char *user; + int port; +}; + BEGIN_DECLS /* + * Set default options from the system krb5.conf or from compile-time + * defaults. + */ +void default_options(krb5_context ctx, struct options *options); + +/* * Given a Kerberos context and a principal name, obtain Kerberos credentials * for that principal and store them in a temporary ticket cache for use by * later operations. kdestroy() then cleans up that cache. @@ -75,12 +105,28 @@ int get_keytab(struct remctl *, krb5_context, const char *type, const char *name, const char *file, const char *srvtab); /* + * Given a remctl object, the Kerberos context, the type for the wallet + * interface, and a file name of a keytab, iterate through every existing + * principal in the keytab in the local realm, get fresh keys for those + * principals, and save the old and new keys to that file. Returns true on + * success and false on partial failure to retrieve all the keys. + */ +bool rekey_keytab(struct remctl *, krb5_context, const char *type, + const char *file); + +/* * Given a filename, some data, and a length, write that data to the given * file with error checking, overwriting any existing contents. */ void overwrite_file(const char *name, const void *data, size_t length); /* + * Given a filename, some data, and a length, append that data to an existing + * file. Dies on any failure. + */ +void append_file(const char *name, const void *data, size_t length); + +/* * Given a filename, some data, and a length, write that data to the given * file safely and atomically by creating file.new, writing the data, linking * file to file.bak, and then renaming file.new to file. diff --git a/client/keytab.c b/client/keytab.c index 5f2076f..9a7734e 100644 --- a/client/keytab.c +++ b/client/keytab.c @@ -17,13 +17,84 @@ #include <util/concat.h> #include <util/messages-krb5.h> #include <util/messages.h> +#include <util/xmalloc.h> + +/* List of principals we have already encountered. */ +struct principal_name { + char *princ; + struct principal_name *next; +}; /* - * Given keytab data as a pointer to memory and a length and the path of a - * second keytab, merge the keys in the memory keytab into the file keytab. - * Currently, this doesn't do any cleanup of old kvnos and doesn't handle - * duplicate kvnos correctly. Dies on any error. + * Given a context, a keytab file, and a realm, return a list of all + * principals in that file. + */ +static struct principal_name * +keytab_principals(krb5_context ctx, const char *file, char *realm) +{ + char *princname = NULL, *princrealm = NULL; + bool found; + krb5_keytab keytab = NULL; + krb5_kt_cursor cursor; + krb5_keytab_entry entry; + krb5_error_code status; + struct principal_name *names = NULL, *current = NULL, *last = NULL; + + memset(&entry, 0, sizeof(entry)); + status = krb5_kt_resolve(ctx, file, &keytab); + if (status != 0) + die_krb5(ctx, status, "cannot open keytab %s", file); + status = krb5_kt_start_seq_get(ctx, keytab, &cursor); + if (status != 0) + die_krb5(ctx, status, "cannot read keytab %s", file); + while ((status = krb5_kt_next_entry(ctx, keytab, &entry, &cursor)) == 0) { + status = krb5_unparse_name(ctx, entry.principal, &princname); + if (status != 0) + die_krb5(ctx, status, "cannot unparse name for a principal"); + + /* Separate into principal and realm. */ + princrealm = strchr(princname, '@'); + if (princrealm != NULL) { + *princrealm = '\0'; + princrealm++; + } + if (princrealm == NULL || strcmp(princrealm, realm) != 0) + continue; + + /* Check to see if the principal has already been listed. */ + found = false; + for (current = names; current != NULL; current = current->next) { + if (strcmp(current->princ, princname) == 0) { + found = true; + break; + } + last = current; + } + if (found == false) { + current = xmalloc(sizeof(struct principal_name)); + current->princ = xstrdup(princname); + current->next = NULL; + if (last == NULL) + names = current; + else + last->next = current; + } + krb5_kt_free_entry(ctx, &entry); + free(princname); + } + if (status != KRB5_KT_END) + die_krb5(ctx, status, "error reading keytab %s", file); + krb5_kt_end_seq_get(ctx, keytab, &cursor); + krb5_kt_close(ctx, keytab); + return names; +} + + +/* + * Given two files containing keytab data, second keytab, merge the keys into + * the new file. Currently, this doesn't do any cleanup of old kvnos and + * doesn't handle duplicate kvnos correctly. Dies on any error. */ static void merge_keytab(krb5_context ctx, const char *newfile, const char *file) @@ -63,9 +134,36 @@ merge_keytab(krb5_context ctx, const char *newfile, const char *file) /* + * Given a remctl object, the type and name of a keytab object, and + * references to keytab data and data length, call the correct wallet + * commands to download a keytab and return the keytab data. Returns the + * status of the remctl command. + */ +static int +download_keytab(struct remctl *r, const char *type, const char *name, + char **data, size_t *length) +{ + const char *command[5]; + int status; + + command[0] = type; + command[1] = "get"; + command[2] = "keytab"; + command[3] = name; + command[4] = NULL; + status = run_command(r, command, data, length); + if (*data == NULL && status == 0) { + warn("no data returned by wallet server"); + return 255; + } + return status; +} + + +/* * 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. + * write it to that file. Returns the status or 255 on an internal error. */ int get_keytab(struct remctl *r, krb5_context ctx, const char *type, @@ -105,3 +203,70 @@ get_keytab(struct remctl *r, krb5_context ctx, const char *type, } return 0; } + + +/* + * Given a remctl object, the Kerberos context, the type for the wallet + * interface, and a file name of a keytab, iterate through every existing + * principal in the keytab in the local realm, get fresh keys for those + * principals, and save the old and new keys to that file. Returns true on + * success and false on partial failure to retrieve all the keys. + */ +bool +rekey_keytab(struct remctl *r, krb5_context ctx, const char *type, + const char *file) +{ + char *realm = NULL; + char *data = NULL; + char *tempfile, *backupfile; + size_t length = 0; + int status; + bool error = false, rekeyed = false; + struct principal_name *names, *current; + + tempfile = concat(file, ".new", (char *) 0); + krb5_get_default_realm(ctx, &realm); + names = keytab_principals(ctx, file, realm); + for (current = names; current != NULL; current = current->next) { + status = download_keytab(r, type, current->princ, &data, &length); + if (status != 0) { + warn("error rekeying for principal %s", current->princ); + if (!rekeyed) + die("aborting, keytab unchanged"); + error = true; + } else if (data != NULL) { + if (access(tempfile, F_OK) == 0) + append_file(tempfile, data, length); + else + write_file(tempfile, data, length); + rekeyed = true; + } + } + + /* If no new keytab data, then leave the keytab as-is. */ + if (!rekeyed) + die("no rekeyable principals found"); + + /* + * Now merge the original keytab file with the one containing the new + * keys. If there is an error, first make a backup of the current keytab + * file as keytab.old. + */ + if (access(file, F_OK) != 0) + link(tempfile, file); + else { + if (error) { + data = read_file(file, &length); + backupfile = concat(file, ".old", (char *) 0); + overwrite_file(backupfile, data, length); + warn("partial failure to rekey keytab %s, old keytab left in %s", + file, backupfile); + free(backupfile); + } + merge_keytab(ctx, tempfile, file); + } + if (unlink(tempfile) < 0) + sysdie("unlink of temporary keytab file %s failed", tempfile); + free(tempfile); + return !error; +} diff --git a/client/options.c b/client/options.c new file mode 100644 index 0000000..2f1de70 --- /dev/null +++ b/client/options.c @@ -0,0 +1,71 @@ +/* + * Set default options for wallet clients. + * + * This file provides the functions to set default options from the krb5.conf + * file for both wallet and wallet-rekey. + * + * Written by Russ Allbery <rra@stanford.edu> + * 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 <client/internal.h> + + +/* + * Load a string option from Kerberos appdefaults. This requires an annoying + * workaround because one cannot specify a default value of NULL. + */ +static void +default_string(krb5_context ctx, const char *opt, const char *defval, + char **result) +{ + if (defval == NULL) + defval = ""; + krb5_appdefault_string(ctx, "wallet", NULL, opt, defval, result); + if (*result != NULL && (*result)[0] == '\0') { + free(*result); + *result = NULL; + } +} + + +/* + * Load a number option from Kerberos appdefaults. The native interface + * doesn't support numbers, so we actually read a string and then convert. + */ +static void +default_number(krb5_context ctx, const char *opt, int defval, int *result) +{ + char *tmp = NULL; + + krb5_appdefault_string(ctx, "wallet", NULL, opt, "", &tmp); + if (tmp != NULL && tmp[0] != '\0') + *result = atoi(tmp); + else + *result = defval; + if (tmp != NULL) + free(tmp); +} + + +/* + * Set option defaults and then get krb5.conf configuration, if any, and + * override the defaults. Later, command-line options will override those + * defaults. + */ +void +default_options(krb5_context ctx, struct options *options) +{ + default_string(ctx, "wallet_type", "wallet", &options->type); + default_string(ctx, "wallet_server", WALLET_SERVER, &options->server); + default_string(ctx, "wallet_principal", NULL, &options->principal); + default_number(ctx, "wallet_port", WALLET_PORT, &options->port); + options->user = NULL; +} diff --git a/client/wallet-rekey.1 b/client/wallet-rekey.1 new file mode 100644 index 0000000..965a123 --- /dev/null +++ b/client/wallet-rekey.1 @@ -0,0 +1,271 @@ +.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.14) +.\" +.\" 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-REKEY 1" +.TH WALLET-REKEY 1 "2010-08-25" "0.12" "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\-rekey \- Client for rekeying a Kerberos keytab using wallet +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +\&\fBwallet-rekey\fR [\fB\-hv\fR] [\fB\-c\fR \fIcommand\fR] [\fB\-k\fR \fIprincipal\fR] + [\fB\-p\fR \fIport\fR] [\fB\-s\fR \fIserver\fR] [\fB\-u\fR \fIprincipal\fR] [\fIkeytab\fR ...] +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +\&\fBwallet-rekey\fR is a specialized client for the wallet system used to +rekey a Kerberos keytab by downloading new keytab objects from wallet for +each principal found in the keytab. For each keytab file listed on the +command line, it walks through the principals in that keytab, finds all +from the local default realm, requests new wallet keytab objects for each +principal (removing the realm when naming the keytab), and merges the new +keys into the keytab. +.PP +If an error occurs before any new keys were downloaded, \fBwallet-rekey\fR +aborts. If some new keys were successfully downloaded, \fBwallet-rekey\fR +warns about errors but continues to rekey all principals that it can. In +this case, a copy of the existing keytab prior to the rekeying is saved in +a file named by appending \f(CW\*(C`.old\*(C'\fR to the file name. +.PP +If no keytab file name is given on the command line, \fBwallet-rekey\fR +attempts to rekey \fI/etc/krb5.keytab\fR, the system default keytab file. +.PP +The new keys are merged into the existing keytab file, but old keys are +not removed. This means that, over time, the keytab will grow and +accumulate old keys, which eventually should no longer be honored. +Administrators may want to run: +.PP +.Vb 1 +\& kadmin \-q \*(Aqktremove \-k <keytab> <principal> old\*(Aq +.Ve +.PP +for \s-1MIT\s0 Kerberos, where <keytab> is the path to the keytab and <principal> +is a principal in the keytab (repeating the command for each principal) +or: +.PP +.Vb 1 +\& ktutil \-k <keytab> purge +.Ve +.PP +for Heimdal. This functionality will eventually be provided by +\&\fBwallet-rekey\fR directly. +.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\-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 \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 "CONFIGURATION" +.IX Header "CONFIGURATION" +The wallet system, including \fBwallet-rekey\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-rekey\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), \fIwallet\fR\|(1) +.PP +This program is part of the wallet system. The current version is available +from <http://www.eyrie.org/~eagle/software/wallet/>. +.PP +\&\fBwallet-rekey\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-rekey.c b/client/wallet-rekey.c new file mode 100644 index 0000000..3a9687c --- /dev/null +++ b/client/wallet-rekey.c @@ -0,0 +1,147 @@ +/* + * A specialized wallet client for rekeying a keytab. + * + * Written by Russ Allbery <rra@stanford.edu> + * and Jon Robertson <jonrober@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 <remctl.h> +#include <errno.h> + +#include <client/internal.h> +#include <util/messages.h> +#include <util/messages-krb5.h> + +/* + * Usage message. Use as a format and pass the port number and default server + * name. + */ +static const char usage_message[] = "\ +Usage: wallet-rekey [options] [<file> ...]\n\ +\n\ +Options:\n\ + -c <command> Command prefix to use (default: wallet)\n\ + -k <principal> Kerberos principal of the server\n\ + -h Display this help\n\ + -p <port> Port of server (default: %d, if zero, remctl default)\n\ + -s <server> Server hostname (default: %s)\n\ + -u <user> Authenticate as <user> before rekeying\n\ + -v Display the version of wallet\n"; + + +/* + * Display the usage message for wallet-rekey. + */ +static void +usage(int status) +{ + fprintf((status == 0) ? stdout : stderr, usage_message, WALLET_PORT, + (WALLET_SERVER == NULL) ? "<none>" : WALLET_SERVER); + exit(status); +} + + +/* + * Main routine. Parse the arguments and then perform the desired operation. + */ +int +main(int argc, char *argv[]) +{ + krb5_context ctx; + krb5_error_code retval; + struct options options; + int option, i; + bool okay = true; + struct remctl *r; + long tmp; + char *end; + + /* Set up logging and identity. */ + message_program_name = "wallet"; + + /* Initialize default configuration. */ + retval = krb5_init_context(&ctx); + if (retval != 0) + die_krb5(ctx, retval, "cannot initialize Kerberos"); + default_options(ctx, &options); + + while ((option = getopt(argc, argv, "c:k:hp:S:s:u:v")) != EOF) { + switch (option) { + case 'c': + options.type = optarg; + break; + case 'k': + options.principal = optarg; + break; + case 'h': + usage(0); + break; + case 'p': + errno = 0; + tmp = strtol(optarg, &end, 10); + if (tmp <= 0 || tmp > 65535 || *end != '\0') + die("invalid port number %s", optarg); + options.port = tmp; + break; + case 's': + options.server = optarg; + break; + case 'u': + options.user = optarg; + break; + case 'v': + printf("%s\n", PACKAGE_STRING); + exit(0); + break; + default: + usage(1); + break; + } + } + argc -= optind; + argv += optind; + + /* + * If no server was set at configure time and none was set on the command + * line or with krb5.conf settings, we can't continue. + */ + if (options.server == NULL) + die("no server specified in krb5.conf or with -s"); + + /* If a user was specified, obtain Kerberos tickets. */ + if (options.user != NULL) + kinit(ctx, options.user); + + /* Open a remctl connection. */ + r = remctl_new(); + if (r == NULL) + sysdie("cannot allocate memory"); + if (!remctl_open(r, options.server, options.port, options.principal)) + die("%s", remctl_error(r)); + + /* + * Rekey all the keytabs given on the command line, or the system keytab + * if none were given. + */ + if (argc == 0) + okay = rekey_keytab(r, ctx, options.type, "/etc/krb5.keytab"); + else { + for (i = 0; i < argc; i++) { + okay = rekey_keytab(r, ctx, options.type, argv[i]); + if (!okay) + break; + } + } + remctl_close(r); + krb5_free_context(ctx); + if (options.user != NULL) + kdestroy(); + exit(okay ? 0 : 1); +} diff --git a/client/wallet-rekey.pod b/client/wallet-rekey.pod new file mode 100644 index 0000000..efe9a0b --- /dev/null +++ b/client/wallet-rekey.pod @@ -0,0 +1,165 @@ +=for stopwords +wallet-rekey rekey rekeying keytab -hv Heimdal remctl remctld PKINIT kinit +appdefaults Allbery + +=head1 NAME + +wallet-rekey - Client for rekeying a Kerberos keytab using wallet + +=head1 SYNOPSIS + +B<wallet-rekey> [B<-hv>] [B<-c> I<command>] [B<-k> I<principal>] + [B<-p> I<port>] [B<-s> I<server>] [B<-u> I<principal>] [I<keytab> ...] + +=head1 DESCRIPTION + +B<wallet-rekey> is a specialized client for the wallet system used to +rekey a Kerberos keytab by downloading new keytab objects from wallet for +each principal found in the keytab. For each keytab file listed on the +command line, it walks through the principals in that keytab, finds all +from the local default realm, requests new wallet keytab objects for each +principal (removing the realm when naming the keytab), and merges the new +keys into the keytab. + +If an error occurs before any new keys were downloaded, B<wallet-rekey> +aborts. If some new keys were successfully downloaded, B<wallet-rekey> +warns about errors but continues to rekey all principals that it can. In +this case, a copy of the existing keytab prior to the rekeying is saved in +a file named by appending C<.old> to the file name. + +If no keytab file name is given on the command line, B<wallet-rekey> +attempts to rekey F</etc/krb5.keytab>, the system default keytab file. + +The new keys are merged into the existing keytab file, but old keys are +not removed. This means that, over time, the keytab will grow and +accumulate old keys, which eventually should no longer be honored. +Administrators may want to run: + + kadmin -q 'ktremove -k <keytab> <principal> old' + +for MIT Kerberos, where <keytab> is the path to the keytab and <principal> +is a principal in the keytab (repeating the command for each principal) +or: + + ktutil -k <keytab> purge + +for Heimdal. This functionality will eventually be provided by +B<wallet-rekey> directly. + +=head1 OPTIONS + +=over 4 + +=item B<-c> I<command> + +The command prefix (remctl type) to use. Normally this is an internal +implementation detail and the default (C<wallet>) 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 +F<krb5.conf>; see L<CONFIGURATION> below. + +=item B<-k> I<principal> + +The service principal of the wallet server. The default is to use the +C<host> principal for the wallet server. The principal chosen must match +one of the keys in the keytab used by B<remctld> on the wallet server. +This option can also be set in F<krb5.conf>; see L<CONFIGURATION> below. + +=item B<-h> + +Display a brief summary of options and exit. All other valid options and +commands are ignored. + +=item B<-p> I<port> + +The port to connect to on the wallet server. The default is the default +remctl port. This option can also be set in F<krb5.conf>; see +L<CONFIGURATION> below. + +=item B<-s> I<server> + +The wallet server to connect to. The default may be set when compiling +the wallet client. If it isn't, either B<-s> must be given or the server +must be set in F<krb5.conf>. See L<CONFIGURATION> below. + +=item B<-u> I<principal> + +Rather than using the user's existing ticket cache for authentication, +authenticate as I<principal> first and use those credentials for +authentication to the wallet server. B<wallet> will prompt for the +password for I<principal>. Non-password authentication methods such as +PKINIT aren't supported; to use those, run B<kinit> first and use an +existing ticket cache. + +=item B<-v> + +Display the version of the B<wallet> client and exit. All other valid +options and commands are ignored. + +=back + +=head1 CONFIGURATION + +The wallet system, including B<wallet-rekey>, can optionally be configured +in the system F<krb5.conf>. It will read the default F<krb5.conf> file +for the Kerberos libraries with which it was compiled. To set an option, +put the option in the [appdefaults] section. B<wallet-rekey> will look +for options either at the top level of the [appdefaults] section or in a +subsection named C<wallet>. For example, the following fragment of a +F<krb5.conf> file would set the default port to 4373 and the default +server to C<wallet.example.org>. + + [appdefaults] + wallet_port = 4373 + wallet = { + wallet_server = wallet.example.org + } + +The supported options are: + +=over 4 + +=item wallet_principal + +The service principal of the wallet server. The default is to use the +C<host> principal for the wallet server. The principal chosen must match +one of the keys in the keytab used by B<remctld> on the wallet server. +The B<-k> command-line option overrides this setting. + +=item wallet_port + +The port to connect to on the wallet server. The default is the default +remctl port. The B<-p> command-line option overrides this setting. + +=item wallet_server + +The wallet server to connect to. The B<-s> command-line option overrides +this setting. The default may be set when compiling the wallet client. +If it isn't, either B<-s> must be given or this parameter must be present +in in F<krb5.conf>. + +=item wallet_type + +The command prefix (remctl type) to use. Normally this is an internal +implementation detail and the default (C<wallet>) 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 B<-c> command-line option +overrides this setting. + +=back + +=head1 SEE ALSO + +kadmin(8), kinit(1), krb5.conf(5), remctl(1), remctld(8), wallet(1) + +This program is part of the wallet system. The current version is available +from L<http://www.eyrie.org/~eagle/software/wallet/>. + +B<wallet-rekey> uses the remctl protocol. For more information about +remctl, see L<http://www.eyrie.org/~eagle/software/remctl/>. + +=head1 AUTHOR + +Russ Allbery <rra@stanford.edu> + +=cut diff --git a/client/wallet.1 b/client/wallet.1 index 7d7004f..0e02fe9 100644 --- a/client/wallet.1 +++ b/client/wallet.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13) +.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.14) .\" .\" Standard preamble: .\" ======================================================================== @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "WALLET 1" -.TH WALLET 1 "2010-03-08" "0.11" "wallet" +.TH WALLET 1 "2010-08-25" "0.12" "wallet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -311,6 +311,14 @@ entry in the special \s-1ACL\s0 \f(CW\*(C`ADMIN\*(C'\fR cannot be removed to pro 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 rename <id> <name>" 4 +.IX Item "acl rename <id> <name>" +Renames the \s-1ACL\s0 identified by <id> to <name>. This changes the +human-readable name, not the underlying numeric \s-1ID\s0, so the \s-1ACL\s0's +associations with objects will be unchanged. The \f(CW\*(C`ADMIN\*(C'\fR \s-1ACL\s0 may not be +renamed. <id> may be either the current name or the numeric \s-1ID\s0. <name> +must not be all-numeric. To rename an \s-1ACL\s0, the current user must be +authorized by 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>. diff --git a/client/wallet.c b/client/wallet.c index e6d8eb9..dc04dcd 100644 --- a/client/wallet.c +++ b/client/wallet.c @@ -22,30 +22,9 @@ #include <util/xmalloc.h> /* - * Basic wallet behavior options set either on the command line or via - * krb5.conf. If set via krb5.conf, we allocate memory for the strings, but - * we never free them. + * Usage message. Use as a format and pass the port number and default server + * name. */ -struct options { - char *type; - char *server; - char *principal; - char *user; - int port; -}; - -/* - * Allow defaults to be set for a particular site with configure options if - * people don't want to use krb5.conf for some reason. - */ -#ifndef WALLET_SERVER -# define WALLET_SERVER NULL -#endif -#ifndef WALLET_PORT -# define WALLET_PORT 0 -#endif - -/* Usage message. Use as a format and pass the port number. */ static const char usage_message[] = "\ Usage: wallet [options] <command> <type> <name> [<arg> ...]\n\ wallet [options] acl <command> <id> [<arg> ...]\n\ @@ -58,11 +37,12 @@ Options:\n\ -p <port> Port of server (default: %d, if zero, remctl default)\n\ -S <srvtab> For the get keytab command, srvtab output file\n\ -s <server> Server hostname (default: %s)\n\ + -u <user> Authenticate as <user> before running command\n\ -v Display the version of wallet\n"; /* - * Display the usage message for remctl. + * Display the usage message for wallet. */ static void usage(int status) @@ -74,59 +54,6 @@ usage(int status) /* - * Load a string option from Kerberos appdefaults. This requires an annoying - * workaround because one cannot specify a default value of NULL. - */ -static void -default_string(krb5_context ctx, const char *opt, const char *defval, - char **result) -{ - if (defval == NULL) - defval = ""; - krb5_appdefault_string(ctx, "wallet", NULL, opt, defval, result); - if (*result != NULL && (*result)[0] == '\0') { - free(*result); - *result = NULL; - } -} - - -/* - * Load a number option from Kerberos appdefaults. The native interface - * doesn't support numbers, so we actually read a string and then convert. - */ -static void -default_number(krb5_context ctx, const char *opt, int defval, int *result) -{ - char *tmp = NULL; - - krb5_appdefault_string(ctx, "wallet", NULL, opt, "", &tmp); - if (tmp != NULL && tmp[0] != '\0') - *result = atoi(tmp); - else - *result = defval; - if (tmp != NULL) - free(tmp); -} - - -/* - * Set option defaults and then get krb5.conf configuration, if any, and - * override the defaults. Later, command-line options will override those - * defaults. - */ -static void -set_defaults(krb5_context ctx, struct options *options) -{ - default_string(ctx, "wallet_type", "wallet", &options->type); - default_string(ctx, "wallet_server", WALLET_SERVER, &options->server); - default_string(ctx, "wallet_principal", NULL, &options->principal); - default_number(ctx, "wallet_port", WALLET_PORT, &options->port); - options->user = NULL; -} - - -/* * Main routine. Parse the arguments and then perform the desired operation. */ int @@ -151,7 +78,7 @@ main(int argc, char *argv[]) retval = krb5_init_context(&ctx); if (retval != 0) die_krb5(ctx, retval, "cannot initialize Kerberos"); - set_defaults(ctx, &options); + default_options(ctx, &options); while ((option = getopt(argc, argv, "c:f:k:hp:S:s:u:v")) != EOF) { switch (option) { @@ -242,6 +169,10 @@ main(int argc, char *argv[]) } else { status = get_file(r, options.type, argv[1], argv[2], file); } + } else if (strcmp(argv[0], "rekey") == 0) { + if (argc > 2) + die("too many arguments"); + status = rekey_keytab(r, ctx, options.type, argv[1]); } else { count = argc + 1; if (strcmp(argv[0], "store") == 0) { diff --git a/client/wallet.pod b/client/wallet.pod index db93700..45969b2 100644 --- a/client/wallet.pod +++ b/client/wallet.pod @@ -5,7 +5,7 @@ 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 +KDC appdefaults remctld Allbery uuencode getacl backend ACL's =head1 SYNOPSIS @@ -210,6 +210,15 @@ accidental lockout, but administrators can remove themselves from the C<ADMIN> ACL and can leave only a non-functioning entry on the ACL. Use caution when removing entries from the C<ADMIN> ACL. +=item acl rename <id> <name> + +Renames the ACL identified by <id> to <name>. This changes the +human-readable name, not the underlying numeric ID, so the ACL's +associations with objects will be unchanged. The C<ADMIN> ACL may not be +renamed. <id> may be either the current name or the numeric ID. <name> +must not be all-numeric. To rename an ACL, the current user must be +authorized by the C<ADMIN> ACL. + =item acl show <id> Display the name, numeric ID, and entries of the ACL <id>. diff --git a/config.h.in b/config.h.in index bf4c54e..d8c5681 100644 --- a/config.h.in +++ b/config.h.in @@ -6,6 +6,10 @@ /* Define if the compiler supports C99 variadic macros. */ #undef HAVE_C99_VAMACROS +/* Define to 1 if you have the declaration of `krb5_kt_free_entry', and to 0 + if you don't. */ +#undef HAVE_DECL_KRB5_KT_FREE_ENTRY + /* Define to 1 if you have the declaration of `snprintf', and to 0 if you don't. */ #undef HAVE_DECL_SNPRINTF @@ -41,6 +45,12 @@ /* 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_free' function. */ +#undef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE + +/* Define if krb5_get_init_creds_opt_free takes two arguments. */ +#undef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_2_ARGS + /* 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 @@ -48,9 +58,6 @@ /* 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 diff --git a/config/wallet b/config/wallet index 06dc39d..19b86fa 100644 --- a/config/wallet +++ b/config/wallet @@ -1,7 +1,9 @@ # /etc/remctl/conf.d/wallet -- Run wallet-backend for the wallet system. # -# This is a remctld configuration fragment to run wallet-backend, which -# implements the server side of the wallet system. +# This is a remctld configuration fragment to run wallet-backend and +# wallet-report, which implement the server side of the wallet system. wallet store /usr/sbin/wallet-backend stdin=4 ANYUSER wallet ALL /usr/sbin/wallet-backend ANYUSER + +wallet-report /usr/sbin/wallet-report /etc/remctl/acl/wallet-report diff --git a/config/wallet-report.acl b/config/wallet-report.acl new file mode 100644 index 0000000..d4c1aa6 --- /dev/null +++ b/config/wallet-report.acl @@ -0,0 +1,6 @@ +# /etc/remctl/acl/wallet-report -- ACL for wallet reporting. +# +# This is the ACL controlling who can run reports against the wallet +# database using wallet-report via remctl. This backend doesn't allow any +# modification of data or retrieval of stored data, but does allow +# examination of all of the metadata in the wallet database. @@ -1,13 +1,13 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for wallet 0.11. +# Generated by GNU Autoconf 2.67 for wallet 0.12. # # 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. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -319,7 +319,7 @@ $as_echo X"$as_dir" | 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" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -359,19 +359,19 @@ else fi # as_fn_arith -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS 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. +# 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 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -533,7 +533,7 @@ 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, +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` @@ -552,8 +552,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='wallet' PACKAGE_TARNAME='wallet' -PACKAGE_VERSION='0.11' -PACKAGE_STRING='wallet 0.11' +PACKAGE_VERSION='0.12' +PACKAGE_STRING='wallet 0.12' PACKAGE_BUGREPORT='rra@stanford.edu' PACKAGE_URL='' @@ -789,8 +789,9 @@ do fi case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. @@ -835,7 +836,7 @@ do 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" + 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 @@ -861,7 +862,7 @@ do 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" + 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 @@ -1065,7 +1066,7 @@ do 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" + 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 @@ -1081,7 +1082,7 @@ do 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" + 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 @@ -1111,8 +1112,8 @@ do | --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." + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" ;; *=*) @@ -1120,7 +1121,7 @@ Try \`$0 --help' for more information." # 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'" ;; + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1138,13 +1139,13 @@ done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error "missing argument to $ac_option" + 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" ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1167,7 +1168,7 @@ do [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac - as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" + 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' @@ -1181,8 +1182,8 @@ target=$target_alias 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 + $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 @@ -1197,9 +1198,9 @@ 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" + 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" + as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. @@ -1238,11 +1239,11 @@ else 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" + 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" + 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 @@ -1268,7 +1269,7 @@ 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.11 to adapt to many kinds of systems. +\`configure' configures wallet 0.12 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1282,7 +1283,7 @@ Configuration: --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 + -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 @@ -1334,7 +1335,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of wallet 0.11:";; + short | recursive ) echo "Configuration of wallet 0.12:";; esac cat <<\_ACEOF @@ -1447,10 +1448,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -wallet configure 0.11 -generated by GNU Autoconf 2.65 +wallet configure 0.12 +generated by GNU Autoconf 2.67 -Copyright (C) 2009 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1520,7 +1521,7 @@ $as_echo "$ac_try_echo"; } >&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 $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : @@ -1544,10 +1545,10 @@ fi 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 : + if eval "test \"\${$3+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 : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -1583,7 +1584,7 @@ if ac_fn_c_try_cpp "$LINENO"; then : else ac_header_preproc=no fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } @@ -1606,17 +1607,15 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} $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 -## ------------------------------- ## +( $as_echo "## ------------------------------- ## ## 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 : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -1680,7 +1679,7 @@ 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 : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1934,7 +1933,7 @@ 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 : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1993,6 +1992,52 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_func +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#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 + # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including @@ -2002,7 +2047,7 @@ 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 : +if eval "test \"\${$4+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2059,7 +2104,7 @@ 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 : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -2103,51 +2148,12 @@ $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.11, which was -generated by GNU Autoconf 2.65. Invocation command line was +It was created by wallet $as_me 0.12, which was +generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2257,11 +2263,9 @@ trap 'exit_status=$? { echo - cat <<\_ASBOX -## ---------------- ## + $as_echo "## ---------------- ## ## Cache variables. ## -## ---------------- ## -_ASBOX +## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( @@ -2295,11 +2299,9 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ) echo - cat <<\_ASBOX -## ----------------- ## + $as_echo "## ----------------- ## ## Output variables. ## -## ----------------- ## -_ASBOX +## ----------------- ##" echo for ac_var in $ac_subst_vars do @@ -2312,11 +2314,9 @@ _ASBOX echo if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## + $as_echo "## ------------------- ## ## File substitutions. ## -## ------------------- ## -_ASBOX +## ------------------- ##" echo for ac_var in $ac_subst_files do @@ -2330,11 +2330,9 @@ _ASBOX fi if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## + $as_echo "## ----------- ## ## confdefs.h. ## -## ----------- ## -_ASBOX +## ----------- ##" echo cat confdefs.h echo @@ -2389,7 +2387,12 @@ _ACEOF ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - ac_site_file1=$CONFIG_SITE + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site @@ -2404,7 +2407,11 @@ do { $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" + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5 ; } fi done @@ -2480,7 +2487,7 @@ if $ac_cache_corrupted; then $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 + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -2495,16 +2502,22 @@ 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 + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi 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 + 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, @@ -2624,11 +2637,11 @@ am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error "unsafe absolute working directory name" "$LINENO" 5;; + 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;; + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5 ;; esac # Do `set' in a subshell so we don't clobber the current shell's @@ -2650,7 +2663,7 @@ if ( # 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 + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi @@ -2660,7 +2673,7 @@ then # Ok. : else - as_fn_error "newly created file is older than distributed files! + 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 @@ -2898,7 +2911,7 @@ done $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 : +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF @@ -2906,7 +2919,7 @@ SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +# 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;; @@ -2952,7 +2965,7 @@ if test "`cd $srcdir && pwd`" != "`pwd`"; then 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 + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi @@ -2968,7 +2981,7 @@ fi # Define the identity of the package. PACKAGE='wallet' - VERSION='0.11' + VERSION='0.12' cat >>confdefs.h <<_ACEOF @@ -3332,8 +3345,8 @@ 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; } +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 @@ -3447,9 +3460,8 @@ 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; }; } +as_fn_error 77 "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; } @@ -3491,8 +3503,8 @@ 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; } +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 @@ -3549,9 +3561,9 @@ $as_echo "$ac_try_echo"; } >&5 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. +as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details." "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi @@ -3602,8 +3614,8 @@ 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; } +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 @@ -4055,7 +4067,7 @@ else # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4071,11 +4083,11 @@ else ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi @@ -4114,7 +4126,7 @@ else # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4130,18 +4142,18 @@ else ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i 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; } +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=c @@ -4202,7 +4214,7 @@ esac 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 + 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 @@ -4268,7 +4280,7 @@ esac 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 + 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 @@ -4400,8 +4412,7 @@ 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 : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -4481,7 +4492,7 @@ $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 : +if eval "test \"\${ac_cv_prog_cc_${ac_cc}_c_o+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -4716,9 +4727,8 @@ 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; }; } +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_long=0 fi @@ -5001,13 +5011,16 @@ $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 + 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" else if test x"$rra_gssapi_root" != x && test -z "$KRB5_CONFIG"; then : @@ -5820,7 +5833,7 @@ $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 + as_fn_error $? "cannot find usable GSS-API library" "$LINENO" 5 fi fi @@ -6557,7 +6570,7 @@ $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 + as_fn_error $? "cannot find usable GSS-API library" "$LINENO" 5 fi fi @@ -6585,8 +6598,8 @@ 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; } +as_fn_error $? "unable to link with remctl library +See \`config.log' for more details" "$LINENO" 5 ; } fi CPPFLAGS="$rra_remctl_save_CPPFLAGS" @@ -6595,9 +6608,6 @@ fi rra_krb5_root= rra_krb5_libdir= rra_krb5_includedir= - KRB5_CPPFLAGS= - KRB5_LDFLAGS= - KRB5_LIBS= @@ -6704,7 +6714,7 @@ 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 + as_fn_error $? "cannot find usable Kerberos v5 library" "$LINENO" 5 fi fi @@ -6838,7 +6848,7 @@ $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 + as_fn_error $? "cannot find usable com_err library" "$LINENO" 5 fi for ac_header in et/com_err.h @@ -7314,6 +7324,62 @@ if test "$ac_res" != no; then : fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing rk_simple_execve" >&5 +$as_echo_n "checking for library containing rk_simple_execve... " >&6; } +if test "${ac_cv_search_rk_simple_execve+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 rk_simple_execve (); +int +main () +{ +return rk_simple_execve (); + ; + return 0; +} +_ACEOF +for ac_lib in '' roken; 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_rk_simple_execve=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_rk_simple_execve+set}" = set; then : + break +fi +done +if test "${ac_cv_search_rk_simple_execve+set}" = set; then : + +else + ac_cv_search_rk_simple_execve=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_rk_simple_execve" >&5 +$as_echo "$ac_cv_search_rk_simple_execve" >&6; } +ac_res=$ac_cv_search_rk_simple_execve +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 @@ -7322,7 +7388,7 @@ 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" +LIBS="-lkrb5 -lasn1 -lcom_err -lcrypto $rra_krb5_extra $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7353,7 +7419,7 @@ 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" + KRB5_LIBS="-lkrb5 -lasn1 -lcom_err -lcrypto $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; } @@ -7717,7 +7783,7 @@ 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 + as_fn_error $? "cannot find usable Kerberos v5 library" "$LINENO" 5 fi fi @@ -8261,6 +8327,62 @@ if test "$ac_res" != no; then : fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing rk_simple_execve" >&5 +$as_echo_n "checking for library containing rk_simple_execve... " >&6; } +if test "${ac_cv_search_rk_simple_execve+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 rk_simple_execve (); +int +main () +{ +return rk_simple_execve (); + ; + return 0; +} +_ACEOF +for ac_lib in '' roken; 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_rk_simple_execve=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_rk_simple_execve+set}" = set; then : + break +fi +done +if test "${ac_cv_search_rk_simple_execve+set}" = set; then : + +else + ac_cv_search_rk_simple_execve=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_rk_simple_execve" >&5 +$as_echo "$ac_cv_search_rk_simple_execve" >&6; } +ac_res=$ac_cv_search_rk_simple_execve +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 @@ -8269,7 +8391,7 @@ 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" +LIBS="-lkrb5 -lasn1 -lcom_err -lcrypto $rra_krb5_extra $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -8300,7 +8422,7 @@ 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" + KRB5_LIBS="-lkrb5 -lasn1 -lcom_err -lcrypto $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; } @@ -8664,7 +8786,7 @@ 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 + as_fn_error $? "cannot find usable Kerberos v5 library" "$LINENO" 5 fi fi @@ -8779,13 +8901,11 @@ rra_krb5_save_CPPFLAGS="$CPPFLAGS" 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 : +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -8793,6 +8913,58 @@ _ACEOF fi done +for ac_func in krb5_get_init_creds_opt_free +do : + ac_fn_c_check_func "$LINENO" "krb5_get_init_creds_opt_free" "ac_cv_func_krb5_get_init_creds_opt_free" +if test "x$ac_cv_func_krb5_get_init_creds_opt_free" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_KRB5_GET_INIT_CREDS_OPT_FREE 1 +_ACEOF + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if krb5_get_init_creds_opt_free takes two arguments" >&5 +$as_echo_n "checking if krb5_get_init_creds_opt_free takes two arguments... " >&6; } +if test "${rra_cv_func_krb5_get_init_creds_opt_free_args+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <krb5.h> +int +main () +{ +krb5_get_init_creds_opt *opts; krb5_context c; + krb5_get_init_creds_opt_free(c, opts); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + rra_cv_func_krb5_get_init_creds_opt_free_args=yes +else + rra_cv_func_krb5_get_init_creds_opt_free_args=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rra_cv_func_krb5_get_init_creds_opt_free_args" >&5 +$as_echo "$rra_cv_func_krb5_get_init_creds_opt_free_args" >&6; } + if test $rra_cv_func_krb5_get_init_creds_opt_free_args = yes; then : + +$as_echo "#define HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_2_ARGS 1" >>confdefs.h + +fi +fi +done + +ac_fn_c_check_decl "$LINENO" "krb5_kt_free_entry" "ac_cv_have_decl_krb5_kt_free_entry" "$ac_includes_default" +if test "x$ac_cv_have_decl_krb5_kt_free_entry" = x""yes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_KRB5_KT_FREE_ENTRY $ac_have_decl +_ACEOF + 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 : @@ -8922,8 +9094,7 @@ 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 : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -9028,22 +9199,19 @@ 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 + /* For now, do not test the preprocessor; as of 2007 there are too many + implementations with broken preprocessors. Perhaps this can + be revisited in 2012. In the meantime, code should not expect + #if to work with literals wider than 32 bits. */ /* 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)]; + ? 1 : -1)]; typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 - ? 1 : -1)]; + ? 1 : -1)]; int i = 63; int main () @@ -9052,40 +9220,40 @@ main () 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)); + | (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 : + 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 + #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; + 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; } @@ -9184,25 +9352,70 @@ _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 +ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf" +if test "x$ac_cv_func_asprintf" = x""yes; then : + $as_echo "#define HAVE_ASPRINTF 1" >>confdefs.h else case " $LIBOBJS " in - *" $ac_func.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" + *" asprintf.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS asprintf.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp" +if test "x$ac_cv_func_mkstemp" = x""yes; then : + $as_echo "#define HAVE_MKSTEMP 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" mkstemp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv" +if test "x$ac_cv_func_setenv" = x""yes; then : + $as_echo "#define HAVE_SETENV 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" setenv.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS setenv.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat" +if test "x$ac_cv_func_strlcat" = x""yes; then : + $as_echo "#define HAVE_STRLCAT 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" strlcat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strlcat.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" +if test "x$ac_cv_func_strlcpy" = x""yes; then : + $as_echo "#define HAVE_STRLCPY 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" strlcpy.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strlcpy.$ac_objext" ;; esac fi -done @@ -9294,6 +9507,8 @@ ac_config_files="$ac_config_files tests/client/full-t" ac_config_files="$ac_config_files tests/client/prompt-t" +ac_config_files="$ac_config_files tests/client/rekey-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 @@ -9377,6 +9592,7 @@ DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= +U= 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$//' @@ -9400,19 +9616,19 @@ else fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error "conditional \"MAINTAINER_MODE\" was never defined. + 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. + 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. + 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. + as_fn_error $? "conditional \"KRB5_USES_COM_ERR\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi @@ -9562,19 +9778,19 @@ export LANGUAGE (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS 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. +# 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 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -9770,7 +9986,7 @@ $as_echo X"$as_dir" | 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" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -9823,8 +10039,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # 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.11, which was -generated by GNU Autoconf 2.65. Invocation command line was +This file was extended by wallet $as_me 0.12, which was +generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -9889,11 +10105,11 @@ _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.11 -configured by $0, generated by GNU Autoconf 2.65, +wallet config.status 0.12 +configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" -Copyright (C) 2009 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -9911,11 +10127,16 @@ 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=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; *) ac_option=$1 ac_optarg=$2 @@ -9937,6 +10158,7 @@ do $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; @@ -9949,7 +10171,7 @@ do ac_need_defaults=false;; --he | --h) # Conflict between --help and --header - as_fn_error "ambiguous option: \`$1' + as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; @@ -9958,7 +10180,7 @@ Try \`$0 --help' for more information.";; ac_cs_silent=: ;; # This is an error. - -*) as_fn_error "unrecognized option: \`$1' + -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" @@ -10020,8 +10242,9 @@ do "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" ;; + "tests/client/rekey-t") CONFIG_FILES="$CONFIG_FILES tests/client/rekey-t" ;; - *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done @@ -10059,7 +10282,7 @@ $debug || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") -} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 +} || 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. @@ -10076,7 +10299,7 @@ if test "x$ac_cr" = x; then 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' + ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi @@ -10090,18 +10313,18 @@ _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 '$'` + 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 + 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 + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -10190,20 +10413,28 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error "could not setup config files machinery" "$LINENO" 5 + || 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 +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries 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/ + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// s/^[^=]*=[ ]*$// }' fi @@ -10231,7 +10462,7 @@ for ac_last_try in false false :; do if test -z "$ac_t"; then break elif $ac_last_try; then - as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -10316,7 +10547,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error "could not setup config headers machinery" "$LINENO" 5 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" @@ -10329,7 +10560,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -10357,7 +10588,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "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'" @@ -10384,7 +10615,7 @@ $as_echo "$as_me: creating $ac_file" >&6;} case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -10521,22 +10752,22 @@ 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 + || 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 +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;} +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 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # @@ -10547,19 +10778,19 @@ which seems to be undefined. Please make sure it is defined." >&2;} $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 + || 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 + || 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 + || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" @@ -10703,6 +10934,7 @@ $as_echo X"$file" | "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 ;; + "tests/client/rekey-t":F) chmod +x tests/client/rekey-t ;; esac done # for ac_tag @@ -10713,7 +10945,7 @@ _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || - as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. @@ -10734,7 +10966,7 @@ if test "$no_create" != yes; then 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 $? + $ac_cs_success || as_fn_exit 1 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 diff --git a/configure.ac b/configure.ac index df97861..ffd7eeb 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl See LICENSE for licensing terms. 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.11], [rra@stanford.edu]) +AC_INIT([wallet], [0.12], [rra@stanford.edu]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_LIBOBJ_DIR([portable]) AC_CONFIG_MACRO_DIR([m4]) @@ -27,8 +27,10 @@ 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_FUNCS([krb5_get_init_creds_opt_free], + [RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS]) +AC_CHECK_DECLS([krb5_kt_free_entry]) AC_CHECK_MEMBERS([krb5_keytab_entry.keyblock], , , [#include <krb5.h>]) RRA_LIB_KRB5_RESTORE @@ -68,4 +70,5 @@ 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/prompt-t], [chmod +x tests/client/prompt-t]) +AC_CONFIG_FILES([tests/client/rekey-t], [chmod +x tests/client/rekey-t]) AC_OUTPUT diff --git a/contrib/wallet-summary b/contrib/wallet-summary index 7a51f9e..b782a97 100755 --- a/contrib/wallet-summary +++ b/contrib/wallet-summary @@ -1,6 +1,6 @@ #!/usr/bin/perl -w # -# wallet-summarize -- Summarize keytabs in the wallet database. +# wallet-summary -- Summarize keytabs in the wallet database. # # Written by Russ Allbery <rra@stanford.edu> # Copyright 2003, 2008, 2010 Board of Trustees, Leland Stanford Jr. University @@ -45,7 +45,7 @@ use vars qw($ADDRESS $DUMPFILE @PATTERNS $REPORTS); use Getopt::Long qw(GetOptions); use File::Path qw(mkpath); use POSIX qw(strftime); -use Wallet::Admin (); +use Wallet::Report (); ############################################################################## # Database queries diff --git a/contrib/wallet-summary.8 b/contrib/wallet-summary.8 index 2974dd0..f91211b 100644 --- a/contrib/wallet-summary.8 +++ b/contrib/wallet-summary.8 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13) +.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.14) .\" .\" Standard preamble: .\" ======================================================================== @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "WALLET-SUMMARY 8" -.TH WALLET-SUMMARY 8 "2010-03-08" "0.11" "wallet" +.TH WALLET-SUMMARY 8 "2010-08-25" "0.12" "wallet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/contrib/wallet-unknown-hosts b/contrib/wallet-unknown-hosts new file mode 100755 index 0000000..fec0956 --- /dev/null +++ b/contrib/wallet-unknown-hosts @@ -0,0 +1,184 @@ +#!/usr/bin/perl -w +# +# wallet-unknown-hosts -- Report host keytabs in wallet for unknown hosts. +# +# Written by Russ Allbery <rra@stanford.edu> +# Copyright 2010 Board of Trustees, Leland Stanford Jr. University +# +# See LICENSE for licensing terms. + +############################################################################## +# Site configuration +############################################################################## + +# The path to the supplemental database used to store last seen times and +# counts. Keys are hostnames, and values are the number of times the hostname +# was not seen in DNS, a comma, and the UNIX seconds since epoch of the first +# run during which the host was not found. +# +# This should probably be in the wallet database, but let's try it here first +# and hammer out the data and then add it there later. +our $HISTORY = '/var/lib/wallet/hosts.db'; + +# Default thresholds for reporting or purging. $MIN is the number of times we +# see the keytab in a row eligible for purge, and $THRESHOLD is the newest +# that the first time can be and still be eligible. +our $MIN = 3; +our $THRESHOLD = time - 30 * 24 * 60 * 60; + +# Set up a Net::DNS resolver that will be used by local_check_keytab. +BEGIN { + use Net::DNS; + our $DNS = Net::DNS::Resolver->new; +} + +# Pre-filter. This is called for all host-based keytabs and is the place to +# apply local exceptions for keytabs that should be retained even though +# there's no corresponding DNS entry. The first argument is the full +# principal name and the second argument is the extracted host. +# +# This function should return 1 if the host is found or if the keytab should +# otherwise not be a candidate for purging, 0 if the keytab should be a +# candidate for purging, and undef if the normal DNS-based check should be +# done. +sub local_check_keytab { + my ($keytab, $host) = @_; + + # Aliases of proxy.best.stanford.edu and www.best.stanford.edu should not + # have host-based keytabs of their own. + my %purge = map { $_ => 1 } + qw(proxy.best.stanford.edu www.best.stanford.edu); + my $query = $DNS->search ($host); + return unless $query; + for my $rr ($query->answer) { + next unless $rr->type eq 'CNAME'; + return 0 if $purge{$rr->cname}; + } + + # Do normal processing by default. + return; +} + +############################################################################## +# Modules and declarations +############################################################################## + +require 5.006; + +use strict; + +use DB_File (); +use Wallet::Report (); +use Wallet::Server (); + +############################################################################## +# Utility functions +############################################################################## + +# Return a list of host-based keytab objects in the wallet database. The +# current heuristic is to look for any keytab object with a principal name +# that includes a slash and at least one period. This may be refined later. +sub list_keytabs { + my $report = Wallet::Report->new; + my @objects = $report->objects ('type', 'keytab'); + if (!@objects and $report->error) { + die $report->error, "\n"; + } + return grep { m%/.+\..+% } map { $$_[1] } @objects; +} + +# Given a host, look it up in DNS and see if it exists. Returns true if the +# host exists and false otherwise. +sub check_host { + my ($host) = @_; + my $addr = gethostbyname $host; + return defined ($addr) ? 1 : 0; +} + +############################################################################## +# Main functions +############################################################################## + +# Do a scan of all host-based keytabs in wallet and record those that are not +# found in DNS or which should not be used according to site configuration. +sub check { + tie %history, 'DB_File', $HISTORY; + my @keytabs = list_keytabs; + for my $keytab (@keytabs) { + my ($host) = (split '/', $keytab)[1]; + my $result = local_check_keytab ($keytab, $host); + unless (defined $result) { + $result = check_host ($host); + } + if ($result) { + delete $history{$keytab}; + } elsif ($history{$keytab}) { + my ($count, $time) = split (',', $history{$keytab}); + $count++; + $history{$keytab} = "$count,$time"; + } else { + $history{$keytab} = '1,' . time; + } + } + untie %history; +} + +# Report on all keytabs that are eligible to be deleted. Takes two values: +# the threshold for the number of times the keytab had to show up as eligible +# for purge, and the threshold for how long the keytab must have been on that +# list (given as a threshold time in seconds since epoch). +sub report { + my ($min, $threshold) = @_; + tie %history, 'DB_File', $HISTORY; + for my $keytab (sort keys %history) { + my ($count, $time) = split (',', $history{$keytab}); + if ($count > $min && $time < $threshold) { + print $keytab, "\n"; + } + } + untie %history; +} + +# Purge eligible keytabs. Takes three values: the user to authenticate as, +# the threshold for the number of times the keytab had to show up as eligible +# for purge, and the threshold for the first date when the keytab was seen +# eligible for purge. Rather than listing the keytabs, this deletes them +# immediately. +sub purge { + my ($user, $min, $threshold) = @_; + my $wallet = Wallet::Server->new ($user, 'localhost'); + tie %history, 'DB_File', $HISTORY; + for my $keytab (sort keys %history) { + my ($count, $time) = split (',', $history{$keytab}); + if ($count > $min && $time < $threshold) { + unless ($wallet->destroy ('keytab', $keytab)) { + warn "$0: cannot destroy keytab $keytab: ", + $wallet->error, "\n"; + } + } + } + untie %history; +} + +############################################################################## +# Main routine +############################################################################## + +my $command = shift or die "Usage: $0 (check | report | purge)\n"; +if ($command eq 'check') { + check; +} elsif ($command eq 'report') { + my ($min, $threshold) = @_; + $min = $MIN unless defined ($min); + die "$0: minimum count must be at least 1\n" if $min < 1; + $threshold = $THRESHOLD unless defined ($threshold); + report ($min, $threshold); +} elsif ($command eq 'purge') { + my $user = $ENV{REMOTE_USER} or die "$0: REMOTE_USER must be set\n"; + $min = $MIN unless defined ($min); + die "$0: minimum count must be at least 1\n" if $min < 1; + $threshold = $THRESHOLD unless defined ($threshold); + purge ($min, $threshold); +} else { + die "$0: unknown command $command\n"; +} diff --git a/docs/stanford-naming b/docs/stanford-naming index f2a45a7..7315c1e 100644 --- a/docs/stanford-naming +++ b/docs/stanford-naming @@ -104,11 +104,10 @@ Object Naming <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. + The Tivoli password or backup encryption key for this server. + Both the password and the encryption key, if used, are stored in + the same file, so both are stored together. This file is found at + /etc/adsm/TSM.PWD. <group>-<service>-config-<name> diff --git a/m4/gssapi.m4 b/m4/gssapi.m4 index 4b08569..0a657ff 100644 --- a/m4/gssapi.m4 +++ b/m4/gssapi.m4 @@ -57,7 +57,8 @@ AC_DEFUN([_RRA_LIB_GSSAPI_REDUCED], AC_CHECK_LIB([gssapi_krb5], [gss_import_name], [GSSAPI_LIBS="-lgssapi_krb5"], [AC_CHECK_LIB([gssapi], [gss_import_name], [GSSAPI_LIBS="-lgssapi"], [AC_CHECK_LIB([gss], [gss_import_name], [GSSAPI_LIBS="-lgss"], - [AC_MSG_ERROR([cannot find usable GSS-API library])])])])]) + [AC_MSG_ERROR([cannot find usable GSS-API library])])])]) + RRA_LIB_GSSAPI_RESTORE]) dnl Does the appropriate library checks for GSS-API linkage when we don't dnl have krb5-config or reduced dependencies. libgss is used as a last @@ -2,7 +2,7 @@ dnl Find the compiler and linker flags for Kerberos v5. dnl 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 --with-krb5-lib configure options to specify non-standard paths to the dnl Kerberos libraries. Uses krb5-config where available unless reduced dnl dependencies is requested. dnl @@ -13,6 +13,9 @@ 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 If KRB5_CPPFLAGS, KRB5_LDFLAGS, or KRB5_LIBS are set before calling these +dnl macros, their values will be added to whatever the macros discover. +dnl 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, @@ -25,8 +28,12 @@ dnl change library ordering in that case. dnl dnl Depends on RRA_ENABLE_REDUCED_DEPENDS and RRA_SET_LDFLAGS. dnl +dnl Also provides RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS, which checks +dnl whether krb5_get_init_creds_opt_free takes one argument or two. Defines +dnl HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_2_ARGS if it takes two arguments. +dnl dnl Written by Russ Allbery <rra@stanford.edu> -dnl Copyright 2005, 2006, 2007, 2008, 2009 +dnl Copyright 2005, 2006, 2007, 2008, 2009, 2010 dnl Board of Trustees, Leland Stanford Jr. University dnl dnl See LICENSE for licensing terms. @@ -99,10 +106,11 @@ AC_DEFUN([_RRA_LIB_KRB5_MANUAL], [AC_CHECK_LIB([nsl], [socket], [LIBS="-lnsl -lsocket $LIBS"], , [-lsocket])]) AC_SEARCH_LIBS([crypt], [crypt]) + AC_SEARCH_LIBS([rk_simple_execve], [roken]) rra_krb5_extra="$LIBS" LIBS="$rra_krb5_save_LIBS" AC_CHECK_LIB([krb5], [krb5_init_context], - [KRB5_LIBS="-lkrb5 -lasn1 -lroken -lcrypto -lcom_err $rra_krb5_extra"], + [KRB5_LIBS="-lkrb5 -lasn1 -lcom_err -lcrypto $rra_krb5_extra"], [AC_CHECK_LIB([krb5support], [krb5int_getspecific], [rra_krb5_extra="-lkrb5support $rra_krb5_extra"], [AC_CHECK_LIB([pthreads], [pthread_setspecific], @@ -125,7 +133,7 @@ AC_DEFUN([_RRA_LIB_KRB5_MANUAL], [AS_IF([test x"$1" = xtrue], [AC_MSG_ERROR([cannot find usable Kerberos v5 library])])], [$rra_krb5_extra])], - [-lasn1 -lroken -lcrypto -lcom_err $rra_krb5_extra]) + [-lasn1 -lcom_err -lcrypto $rra_krb5_extra]) LIBS="$KRB5_LIBS $LIBS" AC_CHECK_FUNCS([krb5_get_error_message], [AC_CHECK_FUNCS([krb5_free_error_message])], @@ -200,9 +208,6 @@ 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]) @@ -230,9 +235,6 @@ AC_DEFUN([RRA_LIB_KRB5_OPTIONAL], rra_krb5_libdir= rra_krb5_includedir= rra_use_kerberos= - KRB5_CPPFLAGS= - KRB5_LDFLAGS= - KRB5_LIBS= AC_SUBST([KRB5_CPPFLAGS]) AC_SUBST([KRB5_LDFLAGS]) AC_SUBST([KRB5_LIBS]) @@ -261,3 +263,20 @@ AC_DEFUN([RRA_LIB_KRB5_OPTIONAL], [_RRA_LIB_KRB5_INTERNAL([false])])]) AS_IF([test x"$KRB5_LIBS" != x], [AC_DEFINE([HAVE_KERBEROS], 1, [Define to enable Kerberos features.])])]) + +dnl Check whether krb5_get_init_creds_opt_free takes one argument or two. +dnl Early Heimdal used to take a single argument. Defines +dnl HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_2_ARGS if it takes two arguments. +dnl +dnl Should be called with RRA_LIB_KRB5_SWITCH active. +AC_DEFUN([RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS], +[AC_CACHE_CHECK([if krb5_get_init_creds_opt_free takes two arguments], + [rra_cv_func_krb5_get_init_creds_opt_free_args], + [AC_TRY_COMPILE([#include <krb5.h>], + [krb5_get_init_creds_opt *opts; krb5_context c; + krb5_get_init_creds_opt_free(c, opts);], + [rra_cv_func_krb5_get_init_creds_opt_free_args=yes], + [rra_cv_func_krb5_get_init_creds_opt_free_args=no])]) + AS_IF([test $rra_cv_func_krb5_get_init_creds_opt_free_args = yes], + [AC_DEFINE([HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_2_ARGS], 1, + [Define if krb5_get_init_creds_opt_free takes two arguments.])])]) diff --git a/m4/remctl.m4 b/m4/remctl.m4 index 8ee3c16..bb3a56f 100644 --- a/m4/remctl.m4 +++ b/m4/remctl.m4 @@ -21,7 +21,7 @@ dnl dnl See LICENSE for licensing terms. 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 versions that include the remctl flags. Used as a wrapper, with dnl RRA_LIB_REMCTL_RESTORE, around tests. AC_DEFUN([RRA_LIB_REMCTL_SWITCH], [rra_remctl_save_CPPFLAGS="$CPPFLAGS" diff --git a/perl/Wallet/ACL/Krb5/Regex.pm b/perl/Wallet/ACL/Krb5/Regex.pm new file mode 100644 index 0000000..52f4bf5 --- /dev/null +++ b/perl/Wallet/ACL/Krb5/Regex.pm @@ -0,0 +1,132 @@ +# Wallet::ACL::Krb5::Regex -- Wallet Kerberos v5 principal regex ACL verifier +# +# Written by Russ Allbery <rra@stanford.edu> +# Copyright 2007, 2010 Board of Trustees, Leland Stanford Jr. University +# +# See LICENSE for licensing terms. + +############################################################################## +# Modules and declarations +############################################################################## + +package Wallet::ACL::Krb5::Regex; +require 5.006; + +use strict; +use vars qw(@ISA $VERSION); + +use Wallet::ACL::Krb5; + +@ISA = qw(Wallet::ACL::Krb5); + +# 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'; + +############################################################################## +# Interface +############################################################################## + +# Returns true if the Perl regular expression specified by the ACL matches +# the provided Kerberos principal. +sub check { + my ($self, $principal, $acl) = @_; + unless ($principal) { + $self->error ('no principal specified'); + return; + } + unless ($acl) { + $self->error ('no ACL specified'); + return; + } + my $regex = eval { qr/$acl/ }; + if ($@) { + $self->error ('malformed krb5-regex ACL'); + return; + } + return ($principal =~ m/$regex/) ? 1 : 0; +} + +1; +__END__ + +############################################################################## +# Documentation +############################################################################## + +=for stopwords +ACL krb5-regex Durkacz Allbery + +=head1 NAME + +Wallet::ACL::Krb5::Regex - Regex wallet ACL verifier for Kerberos principals + +=head1 SYNOPSIS + + my $verifier = Wallet::ACL::Krb5::Regex->new; + my $status = $verifier->check ($principal, $acl); + if (not defined $status) { + die "Something failed: ", $verifier->error, "\n"; + } elsif ($status) { + print "Access granted\n"; + } else { + print "Access denied\n"; + } + +=head1 DESCRIPTION + +Wallet::ACL::Krb5::Regex is the wallet ACL verifier used to verify ACL +lines of type C<krb5-regex>. The value of such an ACL is a Perl regular +expression, and the ACL grants access to a given Kerberos principal if and +only if the regular expression matches that principal. + +=head1 METHODS + +=over 4 + +=item new() + +Creates a new ACL verifier. For this verifier, there is no setup work. + +=item check(PRINCIPAL, ACL) + +Returns true if the Perl regular expression specified by the ACL matches the +PRINCIPAL, false if not, and undef on an error (see L<"DIAGNOSTICS"> below). + +=item error() + +Returns the error if check() returned undef. + +=back + +=head1 DIAGNOSTICS + +=over 4 + +=item malformed krb5-regex ACL + +The ACL parameter to check() was a malformed Perl regular expression. + +=item no principal specified + +The PRINCIPAL parameter to check() was undefined or the empty string. + +=item no ACL specified + +The ACL parameter to check() was undefined or the empty string. + +=back + +=head1 SEE ALSO + +Wallet::ACL(3), Wallet::ACL::Base(3), Wallet::ACL::Krb5(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 AUTHOR + +Ian Durkacz + +=cut diff --git a/perl/Wallet/Report.pm b/perl/Wallet/Report.pm index c743060..5a8dc52 100644 --- a/perl/Wallet/Report.pm +++ b/perl/Wallet/Report.pm @@ -15,12 +15,13 @@ require 5.006; use strict; use vars qw($VERSION); +use Wallet::ACL; 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.02'; +$VERSION = '0.03'; ############################################################################## # Constructor, destructor, and accessors @@ -128,6 +129,15 @@ sub objects_acl { return ($sql, ($acl->id) x 6); } +# Return the SQL statement to find all objects that have been created but +# have never been retrieved (via get). +sub objects_unused { + my ($self) = @_; + my $sql = 'select ob_type, ob_name from objects where ob_downloaded_on + is null order by objects.ob_type, objects.ob_name'; + return ($sql); +} + # 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 @@ -144,7 +154,7 @@ sub objects { if (!defined $type || $type eq '') { ($sql) = $self->objects_all; } else { - if (@args != 1) { + if ($type ne 'unused' && @args != 1) { $self->error ("object searches require one argument to search"); } elsif ($type eq 'type') { ($sql, @search) = $self->objects_type (@args); @@ -154,6 +164,8 @@ sub objects { ($sql, @search) = $self->objects_flag (@args); } elsif ($type eq 'acl') { ($sql, @search) = $self->objects_acl (@args); + } elsif ($type eq 'unused') { + ($sql) = $self->objects_unused (@args); } else { $self->error ("do not know search type: $type"); } @@ -223,6 +235,52 @@ sub acls_unused { return ($sql); } +# Obtain a textual representation of the membership of an ACL, returning undef +# on error and setting the internal error. +sub acl_membership { + my ($self, $id) = @_; + my $acl = eval { Wallet::ACL->new ($id, $self->{dbh}) }; + if ($@) { + $self->error ($@); + return; + } + my @members = map { "$_->[0] $_->[1]" } $acl->list; + if (!@members && $acl->error) { + $self->error ($acl->error); + return; + } + return join ("\n", @members); +} + +# Duplicate ACL detection unfortunately needs to do something more complex +# than just return a SQL statement, so it's handled differently than other +# reports. All the work is done here and the results returned as a list of +# sets of duplicates. +sub acls_duplicate { + my ($self) = @_; + my @acls = sort map { $_->[1] } $self->acls; + return if (!@acls && $self->{error}); + return if @acls < 2; + my %result; + for my $i (0 .. ($#acls - 1)) { + my $members = $self->acl_membership ($acls[$i]); + return unless defined $members; + for my $j (($i + 1) .. $#acls) { + my $check = $self->acl_membership ($acls[$j]); + return unless defined $check; + if ($check eq $members) { + $result{$acls[$i]} ||= []; + push (@{ $result{$acls[$i]} }, $acls[$j]); + } + } + } + my @result; + for my $acl (sort keys %result) { + push (@result, [ $acl, sort @{ $result{$acl} } ]); + } + return @result; +} + # 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 @@ -238,7 +296,9 @@ sub acls { if (!defined $type || $type eq '') { ($sql) = $self->acls_all; } else { - if ($type eq 'entry') { + if ($type eq 'duplicate') { + return $self->acls_duplicate; + } elsif ($type eq 'entry') { if (@args == 0) { $self->error ('ACL searches require an argument to search'); return; @@ -416,20 +476,28 @@ between an empty report and an error. 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 three 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. C<unused> returns all ACLs that are not -referenced by any object. - -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: +currently four search types. C<duplicate> returns sets of duplicate ACLs +(ones with exactly the same entries). 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. C<unused> returns all ACLs +that are not referenced by any object. + +The return value for everything except C<duplicate> 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' ]) +The return value for the C<duplicate> search is sets of ACL names that are +duplicates (have the same entries). For example, if C<d1>, C<d2>, and +C<d3> are all duplicates, and C<o1> and C<o2> are also duplicates, the +result would be: + + ([ 'd1', 'd2', 'd3' ], [ 'o1', 'o2' ]) + 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. @@ -461,13 +529,14 @@ 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, +There are five 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. +or ID on any of the possible ACL settings, not just owner. C<unused> will +return all entries for which a get command has never been issued. 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> diff --git a/perl/Wallet/Schema.pm b/perl/Wallet/Schema.pm index 589a15d..25d48cf 100644 --- a/perl/Wallet/Schema.pm +++ b/perl/Wallet/Schema.pm @@ -220,6 +220,8 @@ Holds the supported ACL schemes and their corresponding Perl classes: insert into acl_schemes (as_name, as_class) values ('krb5', 'Wallet::ACL::Krb5'); insert into acl_schemes (as_name, as_class) + values ('krb5-regex', 'Wallet::ACL::Krb5::Regex'); + insert into acl_schemes (as_name, as_class) values ('netdb', 'Wallet::ACL::NetDB'); insert into acl_schemes (as_name, as_class) values ('netdb-root', 'Wallet::ACL::NetDB::Root'); diff --git a/perl/t/kadmin.t b/perl/t/kadmin.t index e5fb2fa..a1f2876 100755 --- a/perl/t/kadmin.t +++ b/perl/t/kadmin.t @@ -109,4 +109,6 @@ SKIP: { 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'); + + unlink 'krb5cc_test'; } diff --git a/perl/t/keytab.t b/perl/t/keytab.t index b16cea5..fabdc5b 100755 --- a/perl/t/keytab.t +++ b/perl/t/keytab.t @@ -103,8 +103,14 @@ sub enctypes { close KEYTAB; my @enctypes; - open (KLIST, '-|', 'klist', '-ke', 'keytab') - or die "cannot run klist: $!\n"; + my $pid = open (KLIST, '-|'); + if (not defined $pid) { + die "cannot fork: $!\n"; + } elsif ($pid == 0) { + open (STDERR, '>', '/dev/null') or die "cannot reopen stderr: $!\n"; + exec ('klist', '-ke', 'keytab') + or die "cannot run klist: $!\n"; + } local $_; while (<KLIST>) { next unless /^ *\d+ /; diff --git a/perl/t/report.t b/perl/t/report.t index 1dc69f7..363db20 100755 --- a/perl/t/report.t +++ b/perl/t/report.t @@ -7,7 +7,7 @@ # # See LICENSE for licensing terms. -use Test::More tests => 151; +use Test::More tests => 197; use Wallet::Admin; use Wallet::Report; @@ -49,6 +49,12 @@ 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'); +# That object should be unused. +@objects = $report->objects ('unused'); +is (scalar (@objects), 1, ' and that object is unused'); +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; @@ -97,6 +103,14 @@ 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'); +# Both objects should now show as unused. +@objects = $report->objects ('unused'); +is (scalar (@objects), 2, 'There are now two unused objects'); +is ($objects[0][0], 'base', ' and the first has the right type'); +is ($objects[0][1], 'service/admin', ' and the right name'); +is ($objects[1][0], 'base', ' and the second has the right type'); +is ($objects[1][1], 'service/foo', ' and the right name'); + # 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'); @@ -239,6 +253,75 @@ is (scalar (@lines), 1, 'Searching for ACL naming violations finds one'); is ($lines[0][0], 3, ' and the first has the right ID'); is ($lines[0][1], 'second', ' and the right name'); +# Set up a file bucket so that we can create an object we can retrieve. +system ('rm -rf test-files') == 0 or die "cannot remove test-files\n"; +mkdir 'test-files' or die "cannot create test-files: $!\n"; +$Wallet::Config::FILE_BUCKET = 'test-files'; + +# Create a file object and ensure that it shows up in the unused list. +is ($server->create ('file', 'test'), 1, 'Creating file:test succeeds'); +is ($server->owner ('file', 'test', 'ADMIN'), 1, + ' and setting its owner works'); +@objects = $report->objects ('unused'); +is (scalar (@objects), 4, 'There are now four unused objects'); +is ($objects[0][0], 'base', ' and the first has the right type'); +is ($objects[0][1], 'service/admin', ' and the right name'); +is ($objects[1][0], 'base', ' and the second has the right type'); +is ($objects[1][1], 'service/foo', ' and the right name'); +is ($objects[2][0], 'base', ' and the third has the right type'); +is ($objects[2][1], 'service/null', ' and the right name'); +is ($objects[3][0], 'file', ' and the fourth has the right type'); +is ($objects[3][1], 'test', ' and the right name'); + +# Store something and retrieve it, and then check that the file object fell +# off of the list. +is ($server->store ('file', 'test', 'Some data'), 1, + 'Storing data in file:test succeeds'); +is ($server->get ('file', 'test'), 'Some data', ' and retrieving it works'); +@objects = $report->objects ('unused'); +is (scalar (@objects), 3, ' and now there are three unused objects'); +is ($objects[0][0], 'base', ' and the first has the right type'); +is ($objects[0][1], 'service/admin', ' and the right name'); +is ($objects[1][0], 'base', ' and the second has the right type'); +is ($objects[1][1], 'service/foo', ' and the right name'); +is ($objects[2][0], 'base', ' and the third has the right type'); +is ($objects[2][1], 'service/null', ' and the right name'); + +# The third and fourth ACLs are both empty and should show up as duplicate. +@acls = $report->acls ('duplicate'); +is (scalar (@acls), 1, 'There is one set of duplicate ACLs'); +is (scalar (@{ $acls[0] }), 2, ' with two members'); +is ($acls[0][0], 'fourth', ' and the first member is correct'); +is ($acls[0][1], 'third', ' and the second member is correct'); + +# Add the same line to both ACLs. They should still show up as duplicate. +is ($server->acl_add ('fourth', 'base', 'bar'), 1, + 'Adding a line to the fourth ACL works'); +is ($server->acl_add ('third', 'base', 'bar'), 1, + ' and adding a line to the third ACL works'); +@acls = $report->acls ('duplicate'); +is (scalar (@acls), 1, 'There is one set of duplicate ACLs'); +is (scalar (@{ $acls[0] }), 2, ' with two members'); +is ($acls[0][0], 'fourth', ' and the first member is correct'); +is ($acls[0][1], 'third', ' and the second member is correct'); + +# Add another line to the third ACL. Now we match second. +is ($server->acl_add ('third', 'base', 'foo'), 1, + 'Adding another line to the third ACL works'); +@acls = $report->acls ('duplicate'); +is (scalar (@acls), 1, 'There is one set of duplicate ACLs'); +is (scalar (@{ $acls[0] }), 2, ' with two members'); +is ($acls[0][0], 'second', ' and the first member is correct'); +is ($acls[0][1], 'third', ' and the second member is correct'); + +# Add yet another line to the third ACL. Now all ACLs are distinct. +is ($server->acl_add ('third', 'base', 'baz'), 1, + 'Adding another line to the third ACL works'); +@acls = $report->acls ('duplicate'); +is (scalar (@acls), 0, 'There are no duplicate ACLs'); +is ($report->error, undef, ' and no error'); + # Clean up. $admin->destroy; unlink 'wallet-db'; +system ('rm -r test-files') == 0 or die "cannot remove test-files\n"; diff --git a/perl/t/schema.t b/perl/t/schema.t index 7f0aea4..40759db 100755 --- a/perl/t/schema.t +++ b/perl/t/schema.t @@ -21,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), 28, ' and returns the right number of statements'); +is (scalar (@sql), 29, ' and returns the right number of statements'); # Connect to a database and test create. db_setup; diff --git a/perl/t/verifier.t b/perl/t/verifier.t index 74d7ba8..f56f5fa 100755 --- a/perl/t/verifier.t +++ b/perl/t/verifier.t @@ -3,14 +3,15 @@ # Tests for the basic wallet ACL verifiers. # # 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. -use Test::More tests => 47; +use Test::More tests => 57; use Wallet::ACL::Base; use Wallet::ACL::Krb5; +use Wallet::ACL::Krb5::Regex; use Wallet::ACL::NetDB; use Wallet::ACL::NetDB::Root; use Wallet::Config; @@ -39,6 +40,21 @@ is ($verifier->error, 'no principal specified', ' and right error'); is ($verifier->check ('rra@stanford.edu', ''), undef, 'Empty ACL'); is ($verifier->error, 'malformed krb5 ACL', ' and right error'); +$verifier = Wallet::ACL::Krb5::Regex->new; +isa_ok ($verifier, 'Wallet::ACL::Krb5::Regex', 'krb5-regex verifier'); +is ($verifier->check ('rra@stanford.edu', '.*@stanford\.edu\z'), 1, + 'Simple check'); +is ($verifier->check ('rra@stanford.edu', '^a.*@stanford\.edu'), 0, + 'Simple failure'); +is ($verifier->error, undef, 'No error set'); +is ($verifier->check (undef, '^rra@stanford\.edu\z'), undef, + 'Undefined principal'); +is ($verifier->error, 'no principal specified', ' and right error'); +is ($verifier->check ('rra@stanford.edu', ''), undef, 'Empty ACL'); +is ($verifier->error, 'no ACL specified', ' and right error'); +is ($verifier->check ('rra@stanford.edu', '(rra'), undef, 'Malformed regex'); +is ($verifier->error, 'malformed krb5-regex ACL', ' and right error'); + # Tests for the NetDB verifiers. Skip these if we don't have a keytab or if # we can't find remctld. SKIP: { diff --git a/portable/krb5-extra.c b/portable/krb5-extra.c index dcddbe4..89ccbde 100644 --- a/portable/krb5-extra.c +++ b/portable/krb5-extra.c @@ -97,7 +97,8 @@ krb5_free_error_message(krb5_context ctx UNUSED, const char *msg) * 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) +krb5_get_init_creds_opt_alloc(krb5_context ctx UNUSED, + krb5_get_init_creds_opt **opts) { *opts = calloc(1, sizeof(krb5_get_init_creds_opt)); if (*opts == NULL) diff --git a/portable/krb5.h b/portable/krb5.h index d9ef283..3b5700b 100644 --- a/portable/krb5.h +++ b/portable/krb5.h @@ -23,10 +23,17 @@ #ifndef PORTABLE_KRB5_H #define PORTABLE_KRB5_H 1 -#include <config.h> +/* + * Allow inclusion of config.h to be skipped, since sometimes we have to use a + * stripped-down version of config.h with a different name. + */ +#ifndef CONFIG_H_INCLUDED +# include <config.h> +#endif #include <portable/macros.h> #include <krb5.h> +#include <stdlib.h> BEGIN_DECLS @@ -50,27 +57,39 @@ 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. + * Both current MIT and current Heimdal prefer _opt_alloc and _opt_free, 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 +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE +# ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_2_ARGS +# define krb5_get_init_creds_opt_free(c, o) krb5_get_init_creds_opt_free(o) +# endif +#else +# define krb5_get_init_creds_opt_free(c, o) free(o) +#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 +/* + * Heimdal: krb5_kt_free_entry, MIT: krb5_free_keytab_entry_contents. We + * check for the declaration rather than the function since the function is + * present in older MIT Kerberos libraries but not prototyped. + */ +#if !HAVE_DECL_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 + * there's an accessor macro that returns the krb5_data pointer, which * requires more work to get at the underlying char *. */ #ifndef HAVE_KRB5_PRINCIPAL_GET_REALM diff --git a/server/keytab-backend.8 b/server/keytab-backend.8 index 7a08ede..2ad3d61 100644 --- a/server/keytab-backend.8 +++ b/server/keytab-backend.8 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13) +.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.14) .\" .\" Standard preamble: .\" ======================================================================== @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "KEYTAB-BACKEND 8" -.TH KEYTAB-BACKEND 8 "2010-03-08" "0.11" "wallet" +.TH KEYTAB-BACKEND 8 "2010-08-25" "0.12" "wallet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/server/wallet-admin.8 b/server/wallet-admin.8 index bc5c7ea..295fce2 100644 --- a/server/wallet-admin.8 +++ b/server/wallet-admin.8 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13) +.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.14) .\" .\" Standard preamble: .\" ======================================================================== @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "WALLET-ADMIN 8" -.TH WALLET-ADMIN 8 "2010-03-08" "0.11" "wallet" +.TH WALLET-ADMIN 8 "2010-08-25" "0.12" "wallet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/server/wallet-backend b/server/wallet-backend index 0a611db..52e9857 100755 --- a/server/wallet-backend +++ b/server/wallet-backend @@ -147,7 +147,7 @@ sub command { if ($command eq 'acl') { my $action = shift @args; if ($action eq 'add') { - check_args (3, 3, [], @args); + check_args (3, 3, [3], @args); $server->acl_add (@args) or failure ($server->error, @_); } elsif ($action eq 'create') { check_args (1, 1, [], @args); @@ -164,7 +164,7 @@ sub command { failure ($server->error, @_); } } elsif ($action eq 'remove') { - check_args (3, 3, [], @args); + check_args (3, 3, [3], @args); $server->acl_remove (@args) or failure ($server->error, @_); } elsif ($action eq 'rename') { check_args (2, 2, [], @args); diff --git a/server/wallet-backend.8 b/server/wallet-backend.8 index 47b3e3b..1ecad1a 100644 --- a/server/wallet-backend.8 +++ b/server/wallet-backend.8 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13) +.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.14) .\" .\" Standard preamble: .\" ======================================================================== @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "WALLET-BACKEND 8" -.TH WALLET-BACKEND 8 "2010-03-08" "0.11" "wallet" +.TH WALLET-BACKEND 8 "2010-08-25" "0.12" "wallet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/server/wallet-report b/server/wallet-report index 435fb73..98fd07a 100755 --- a/server/wallet-report +++ b/server/wallet-report @@ -8,12 +8,31 @@ # See LICENSE for licensing terms. ############################################################################## -# Declarations and site configuration +# Declarations and globals ############################################################################## use strict; use Wallet::Report; +# The help output, sent in reply to the help command. Lists each supported +# report command with a brief description of what it does. +our $HELP = <<'EOH'; +Wallet reporting help: + acls All ACLs + acls duplicate ACLs that duplicate another + acls empty All empty ACLs + acls entry <scheme> <id> ACLs containing this entry (wildcarded) + acls unused ACLs that are not referenced by any object + audit acls name ACLs failing the naming policy + audit objects name Objects failing the naming policy + objects All objects + objects acl <acl> Objects granting permissions to that ACL + objects flag <flag> Objects with that flag set + objects owner <owner> Objects owned by that owner + objects type <type> Objects of that type + objects unused Objects that have never been stored/gotten +EOH + ############################################################################## # Implementation ############################################################################## @@ -32,8 +51,14 @@ sub command { 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"; + if (@args && $args[0] eq 'duplicate') { + for my $group (@acls) { + print join (' ', @$group), "\n"; + } + } else { + for my $acl (sort { $$a[1] cmp $$b[1] } @acls) { + print "$$acl[1] (ACL ID: $$acl[0])\n"; + } } } elsif ($command eq 'audit') { die "too many arguments to audit\n" if @args > 2; @@ -49,6 +74,8 @@ sub command { print join (' ', @$item), "\n"; } } + } elsif ($command eq 'help') { + print $HELP; } elsif ($command eq 'objects') { die "too many arguments to objects\n" if @args > 2; my @objects = $report->objects (@args); @@ -110,13 +137,16 @@ B<wallet-report> takes no traditional options. =item acls +=item acls duplicate + =item acls empty =item acls entry <scheme> <identifier> =item acls unused -Returns a list of ACLs in the database. ACLs will be listed in the form: +Returns a list of ACLs in the database. Except for the C<duplicate> +report, ACLs will be listed in the form: <name> (ACL ID: <id>) @@ -124,6 +154,10 @@ 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. +For the C<duplicate> report, the output will instead be one duplicate set +per line. This will be a set of ACLs that all have the same entries. +Only the names will be given, separated by spaces. + 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. @@ -132,6 +166,12 @@ The currently supported ACL search types are: =over 4 +=item acls duplicate + +Returns all sets of ACLs that are duplicates, meaning that they contain +exactly the same entries. Each line will be the names of the ACLs in a +set of duplicates, separated by spaces. + =item acls empty Returns all ACLs which have no entries, generally so that abandoned ACLs @@ -167,6 +207,10 @@ 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 object or ACL. +=item help + +Displays a summary of all available commands. + =item objects =item objects acl <acl> @@ -177,6 +221,8 @@ one line per object or ACL. =item objects type <type> +=item objects unused + Returns a list of objects in the database. Objects will be listed in the form: @@ -210,6 +256,11 @@ Returns all objects owned by the given ACL name or ID. Returns all objects of the given type. +=item objects unused + +Returns all objects that have never been downloaded (have never been the +target of a get command). + =back =item owners <type-pattern> <name-pattern> diff --git a/server/wallet-report.8 b/server/wallet-report.8 index cd56501..0600736 100644 --- a/server/wallet-report.8 +++ b/server/wallet-report.8 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.13) +.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.14) .\" .\" Standard preamble: .\" ======================================================================== @@ -124,7 +124,7 @@ .\" ======================================================================== .\" .IX Title "WALLET-REPORT 8" -.TH WALLET-REPORT 8 "2010-03-08" "0.11" "wallet" +.TH WALLET-REPORT 8 "2010-08-25" "0.12" "wallet" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -151,6 +151,8 @@ translates command strings into method calls and returns the results. .IP "acls" 4 .IX Item "acls" .PD 0 +.IP "acls duplicate" 4 +.IX Item "acls duplicate" .IP "acls empty" 4 .IX Item "acls empty" .IP "acls entry <scheme> <identifier>" 4 @@ -158,7 +160,8 @@ translates command strings into method calls and returns the results. .IP "acls unused" 4 .IX Item "acls unused" .PD -Returns a list of ACLs in the database. ACLs will be listed in the form: +Returns a list of ACLs in the database. Except for the \f(CW\*(C`duplicate\*(C'\fR +report, ACLs will be listed in the form: .Sp .Vb 1 \& <name> (ACL ID: <id>) @@ -168,12 +171,21 @@ 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 +For the \f(CW\*(C`duplicate\*(C'\fR report, the output will instead be one duplicate set +per line. This will be a set of ACLs that all have the same entries. +Only the names will be given, separated by spaces. +.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 duplicate" 4 +.IX Item "acls duplicate" +Returns all sets of ACLs that are duplicates, meaning that they contain +exactly the same entries. Each line will be the names of the ACLs in a +set of duplicates, separated by spaces. .IP "acls empty" 4 .IX Item "acls empty" Returns all ACLs which have no entries, generally so that abandoned ACLs @@ -212,6 +224,9 @@ and ACLs in the form: 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 object or \s-1ACL\s0. +.IP "help" 4 +.IX Item "help" +Displays a summary of all available commands. .IP "objects" 4 .IX Item "objects" .PD 0 @@ -223,6 +238,8 @@ one line per object or \s-1ACL\s0. .IX Item "objects owner <owner>" .IP "objects type <type>" 4 .IX Item "objects type <type>" +.IP "objects unused" 4 +.IX Item "objects unused" .PD Returns a list of objects in the database. Objects will be listed in the form: @@ -253,6 +270,10 @@ Returns all objects owned by the given \s-1ACL\s0 name or \s-1ID\s0. .IP "objects type <type>" 4 .IX Item "objects type <type>" Returns all objects of the given type. +.IP "objects unused" 4 +.IX Item "objects unused" +Returns all objects that have never been downloaded (have never been the +target of a get command). .RE .RS 4 .RE diff --git a/tests/TESTS b/tests/TESTS index 161941c..54b8190 100644 --- a/tests/TESTS +++ b/tests/TESTS @@ -1,6 +1,7 @@ client/basic client/full client/prompt +client/rekey docs/pod docs/pod-spelling portable/asprintf diff --git a/tests/client/basic-t.in b/tests/client/basic-t.in index 86e24d5..11f0bce 100644 --- a/tests/client/basic-t.in +++ b/tests/client/basic-t.in @@ -114,10 +114,10 @@ rm -f srvtab srvtab.bak # Test keytab merging. 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 +ktutil_list keytab klist-seen +ktutil_list data/fake-keytab-merge klist-good ok '...and the merged keytab is correct' cmp klist-seen klist-good -rm -f keytab klist-seen klist-good +rm -f keytab klist-good klist-seen # Test srvtab download into a merged keytab with an older version. cp data/fake-keytab-old keytab diff --git a/tests/client/rekey-t.in b/tests/client/rekey-t.in new file mode 100644 index 0000000..390a362 --- /dev/null +++ b/tests/client/rekey-t.in @@ -0,0 +1,100 @@ +#! /bin/sh +# +# Test suite for the wallet-rekey command-line client. +# +# Written by Russ Allbery <rra@stanford.edu> +# Copyright 2006, 2007, 2008, 2010 +# Board of Trustees, Leland Stanford Jr. University +# +# See LICENSE for licensing terms. + +# Load the test library. +. "$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 + krb5conf="$p" + sed -e '/^[ ]*test-k5.stanford.edu =/,/}/d' \ + -e 's/\(default_realm.*=\) .*/\1 test-k5.stanford.edu/' \ + -e 's/^[ ]*wallet_.*//' \ + -e '/^[ ]*wallet[ ]*=[ ]*{/,/}/d' \ + "$p" > ./krb5.conf + KRB5_CONFIG="./krb5.conf" + export KRB5_CONFIG + break + fi +done +if [ -z "$krb5conf" ] ; then + skip_all 'no krb5.conf found, put one in tests/data/krb5.conf' +fi + +# Test setup. +kerberos_setup +if [ $? != 0 ] ; then + rm krb5.conf + skip_all 'Kerberos tests not configured' +elif [ -z '@REMCTLD@' ] ; then + rm krb5.conf + skip_all 'No remctld found' +else + plan 9 +fi +remctld_start '@REMCTLD@' "$SOURCE/data/basic.conf" +wallet="$BUILD/../client/wallet-rekey" + +# Rekeying should result in a merged keytab with both the old and new keys. +cp data/fake-keytab-old keytab +ok_program 'basic wallet-rekey' 0 '' \ + "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet keytab +ktutil_list keytab klist-seen +ktutil_list data/fake-keytab-rekey klist-good +ok '...and the rekeyed keytab is correct' cmp klist-seen klist-good +rm -f keytab klist-good klist-seen + +# Rekeying a keytab that contains no principals in the local domain should +# produce an error message and do nothing. +cp data/fake-keytab-foreign keytab +ok_program 'foreign wallet-rekey' 1 'wallet: no rekeyable principals found' \ + "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet keytab +ok '...and the keytab was untouched' cmp keytab data/fake-keytab-foreign +rm -f keytab + +# Rekeying a keytab where we can't retrieve the principal should produce an +# error message and abort when it's the first principal. +cp data/fake-keytab-unknown keytab +ok_program 'unknown wallet-rekey' 1 \ +'wallet: Unknown keytab service/real-keytab +wallet: error rekeying for principal service/real-keytab +wallet: aborting, keytab unchanged' \ + "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet keytab +ok '...and the keytab was untouched' cmp keytab data/fake-keytab-unknown +rm -f keytab + +# Rekeying a keytab where we can't retrieve a later principal should leave the +# original keytab as keytab.old and store, in the new keytab, only the things +# that it was able to rekey. +cp data/fake-keytab-partial keytab +ok_program 'partial wallet-rekey' 1 \ +'wallet: Unknown keytab service/real-keytab +wallet: error rekeying for principal service/real-keytab +wallet: partial failure to rekey keytab keytab, old keytab left in keytab.old'\ + "$wallet" -k "$principal" -p 14373 -s localhost -c fake-wallet keytab +ktutil_list keytab klist-seen +ktutil_list data/fake-keytab-partial-result klist-good +ok '...and the rekeyed keytab is correct' cmp klist-seen klist-good +ok '...and the backup keytab is correct' \ + cmp keytab.old data/fake-keytab-partial +rm -f keytab keytab.old klist-seen klist-good + +# Clean up. +rm -f autocreated krb5.conf +remctld_stop +kerberos_cleanup diff --git a/tests/data/fake-keytab b/tests/data/fake-keytab Binary files differindex 714d9b6..6a13fd6 100644 --- a/tests/data/fake-keytab +++ b/tests/data/fake-keytab diff --git a/tests/data/fake-keytab-foreign b/tests/data/fake-keytab-foreign Binary files differnew file mode 100644 index 0000000..efbc5ed --- /dev/null +++ b/tests/data/fake-keytab-foreign diff --git a/tests/data/fake-keytab-merge b/tests/data/fake-keytab-merge Binary files differindex 31ddc49..4858eb4 100644 --- a/tests/data/fake-keytab-merge +++ b/tests/data/fake-keytab-merge diff --git a/tests/data/fake-keytab-old b/tests/data/fake-keytab-old Binary files differindex 6a13fd6..f7ee9c0 100644 --- a/tests/data/fake-keytab-old +++ b/tests/data/fake-keytab-old diff --git a/tests/data/fake-keytab-partial b/tests/data/fake-keytab-partial Binary files differnew file mode 100644 index 0000000..86587aa --- /dev/null +++ b/tests/data/fake-keytab-partial diff --git a/tests/data/fake-keytab-partial-result b/tests/data/fake-keytab-partial-result Binary files differnew file mode 100644 index 0000000..a265ccc --- /dev/null +++ b/tests/data/fake-keytab-partial-result diff --git a/tests/data/fake-keytab-rekey b/tests/data/fake-keytab-rekey Binary files differnew file mode 100644 index 0000000..4e7a507 --- /dev/null +++ b/tests/data/fake-keytab-rekey diff --git a/tests/data/fake-keytab-unknown b/tests/data/fake-keytab-unknown Binary files differnew file mode 100644 index 0000000..0827e74 --- /dev/null +++ b/tests/data/fake-keytab-unknown diff --git a/tests/data/fake-srvtab b/tests/data/fake-srvtab Binary files differindex f454af2..0b4af6b 100644 --- a/tests/data/fake-srvtab +++ b/tests/data/fake-srvtab diff --git a/tests/docs/pod-spelling-t b/tests/docs/pod-spelling-t index 6993e4c..eaa7dd6 100755 --- a/tests/docs/pod-spelling-t +++ b/tests/docs/pod-spelling-t @@ -47,8 +47,8 @@ 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); +} qw(client/wallet.pod client/wallet-rekey.pod server/keytab-backend + server/wallet-admin server/wallet-backend server/wallet-report); plan tests => scalar @pod; # Finally, do the checks. diff --git a/tests/docs/pod-t b/tests/docs/pod-t index f92ba2c..e25ade2 100755 --- a/tests/docs/pod-t +++ b/tests/docs/pod-t @@ -12,8 +12,9 @@ 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 @files = qw(client/wallet.pod client/wallet-rekey.pod server/keytab-backend + server/wallet-admin server/wallet-backend + server/wallet-report); my $total = scalar (@files); plan tests => $total; for my $file (@files) { diff --git a/tests/portable/snprintf-t.c b/tests/portable/snprintf-t.c index ca6ae61..fd4c228 100644 --- a/tests/portable/snprintf-t.c +++ b/tests/portable/snprintf-t.c @@ -2,7 +2,7 @@ * snprintf test suite. * * Written by Russ Allbery <rra@stanford.edu> - * Copyright 2009 Board of Trustees, Leland Stanford Jr. University + * 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, @@ -17,6 +17,12 @@ #include <tests/tap/basic.h> /* + * Disable the requirement that format strings be literals. We need variable + * formats for easy testing. + */ +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +/* * Intentionally don't add the printf attribute here since we pass a * zero-length printf format during testing and don't want warnings. */ @@ -86,7 +92,7 @@ static unsigned long long ullong_nums[] = { static void -test_format(bool truncate, const char *expected, int count, +test_format(bool trunc, const char *expected, int count, const char *format, ...) { char buf[128]; @@ -94,7 +100,7 @@ test_format(bool truncate, const char *expected, int count, va_list args; va_start(args, format); - result = test_vsnprintf(buf, truncate ? 32 : sizeof(buf), format, args); + result = test_vsnprintf(buf, trunc ? 32 : sizeof(buf), format, args); va_end(args); is_string(expected, buf, "format %s, wanted %s", format, expected); is_int(count, result, "...and output length correct"); diff --git a/tests/runtests.c b/tests/runtests.c index 1670012..ab77629 100644 --- a/tests/runtests.c +++ b/tests/runtests.c @@ -8,22 +8,41 @@ * Expects a list of executables located in the given file, one line per * executable. For each one, runs it as part of a test suite, reporting * results. Test output should start with a line containing the number of - * tests (numbered from 1 to this number), and then each line should be in the - * following format: + * tests (numbered from 1 to this number), optionally preceded by "1..", + * although that line may be given anywhere in the output. Each additional + * line should be in the following format: * * ok <number> * not ok <number> * ok <number> # skip + * not ok <number> # todo * - * 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). This is a subset - * of TAP as documented in Test::Harness::TAP, which comes with Perl. + * where <number> is the number of the test. An optional comment is permitted + * after the number if preceded by whitespace. ok indicates success, not ok + * indicates failure. "# skip" and "# todo" are a special cases of a comment, + * and must start with exactly that formatting. They indicate the test was + * skipped for some reason (maybe because it doesn't apply to this platform) + * or is testing something known to currently fail. The text following either + * "# skip" or "# todo" and whitespace is the reason. + * + * As a special case, the first line of the output may be in the form: + * + * 1..0 # skip some reason + * + * which indicates that this entire test case should be skipped and gives a + * reason. + * + * Any other lines are ignored, although for compliance with the TAP protocol + * all lines other than the ones in the above format should be sent to + * standard error rather than standard output and start with #. + * + * This is a subset of TAP as documented in Test::Harness::TAP or + * TAP::Parser::Grammar, 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, 2009 + * Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010 * Russ Allbery <rra@stanford.edu> * * Permission is hereby granted, free of charge, to any person obtaining a @@ -88,6 +107,14 @@ enum test_status { TEST_INVALID }; +/* Indicates the state of our plan. */ +enum plan_status { + PLAN_INIT, /* Nothing seen yet. */ + PLAN_FIRST, /* Plan seen before any tests. */ + PLAN_PENDING, /* Test seen and no plan yet. */ + PLAN_FINAL /* Plan seen after some tests. */ +}; + /* Error exit statuses for test processes. */ #define CHILDERR_DUP 100 /* Couldn't redirect stderr or stdout. */ #define CHILDERR_EXEC 101 /* Couldn't exec child process. */ @@ -97,12 +124,14 @@ enum test_status { struct testset { 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. */ - int passed; /* Count of passing tests. */ - int failed; /* Count of failing lists. */ - int skipped; /* Count of skipped tests (passed). */ + enum plan_status plan; /* The status of our plan. */ + unsigned long count; /* Expected count of tests. */ + unsigned long current; /* The last seen test number. */ + unsigned int length; /* The length of the last status message. */ + unsigned long passed; /* Count of passing tests. */ + unsigned long failed; /* Count of failing lists. */ + unsigned long skipped; /* Count of skipped tests (passed). */ + unsigned long allocated; /* The size of the results table. */ enum test_status *results; /* Table of results by test number. */ int aborted; /* Whether the set as aborted. */ int reported; /* Whether the results were reported. */ @@ -131,8 +160,9 @@ Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ -------------------------- -------------- ---- ---- ------------------------"; /* Include the file name and line number in malloc failures. */ -#define xmalloc(size) x_malloc((size), __FILE__, __LINE__) -#define xstrdup(p) x_strdup((p), __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__) /* @@ -164,7 +194,7 @@ x_malloc(size_t size, const char *file, int line) void *p; p = malloc(size); - if (!p) + if (p == NULL) sysdie("failed to malloc %lu bytes at %s line %d", (unsigned long) size, file, line); return p; @@ -172,6 +202,20 @@ x_malloc(size_t size, const char *file, int line) /* + * Reallocate memory, reporting a fatal error and exiting on failure. + */ +static void * +x_realloc(void *p, size_t size, const char *file, int line) +{ + p = realloc(p, size); + if (p == NULL) + sysdie("failed to realloc %lu bytes at %s line %d", + (unsigned long) size, file, line); + return p; +} + + +/* * Copy a string, reporting a fatal error and exiting on failure. */ static char * @@ -182,7 +226,7 @@ x_strdup(const char *s, const char *file, int line) len = strlen(s) + 1; p = malloc(len); - if (!p) + if (p == NULL) sysdie("failed to strdup %lu bytes at %s line %d", (unsigned long) len, file, line); memcpy(p, s, len); @@ -235,62 +279,6 @@ skip_whitespace(const char *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 - * otherwise. - */ -static int -test_init(const char *line, struct testset *ts) -{ - int i; - - /* - * Prefer a simple number of tests, but if the count is given as a range - * such as 1..10, accept that too for compatibility with Perl's - * Test::Harness. - */ - line = skip_whitespace(line); - if (strncmp(line, "1..", 3) == 0) - line += 3; - - /* - * 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("ABORTED (invalid test count)"); - ts->aborted = 1; - ts->reported = 1; - return 0; - } - ts->count = i; - ts->results = xmalloc(ts->count * sizeof(enum test_status)); - for (i = 0; i < ts->count; i++) - ts->results[i] = TEST_INVALID; - return 1; -} - - -/* * Start a program, connecting its stdout to a pipe on our end and its stderr * to /dev/null, and storing the file descriptor to read from in the two * argument. Returns the PID of the new process. Errors are fatal. @@ -340,7 +328,7 @@ test_start(const char *path, int *fd) static void test_backspace(struct testset *ts) { - int i; + unsigned int i; if (!isatty(STDOUT_FILENO)) return; @@ -355,6 +343,87 @@ test_backspace(struct testset *ts) /* + * Read the plan line of test output, which should contain the range of test + * numbers. We may initialize the testset structure here if we haven't yet + * seen a test. Return true if initialization succeeded and the test should + * continue, false otherwise. + */ +static int +test_plan(const char *line, struct testset *ts) +{ + unsigned long i; + long n; + + /* + * Accept a plan without the leading 1.. for compatibility with older + * versions of runtests. This will only be allowed if we've not yet seen + * a test result. + */ + line = skip_whitespace(line); + if (strncmp(line, "1..", 3) == 0) + line += 3; + + /* + * 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. If we do skip the whole file, zero out all of + * our statistics, since they're no longer relevant. + */ + n = strtol(line, (char **) &line, 10); + if (n == 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; + ts->count = 0; + ts->passed = 0; + ts->skipped = 0; + ts->failed = 0; + return 0; + } + } + } + if (n <= 0) { + puts("ABORTED (invalid test count)"); + ts->aborted = 1; + ts->reported = 1; + return 0; + } + if (ts->plan == PLAN_INIT && ts->allocated == 0) { + ts->count = n; + ts->allocated = n; + ts->plan = PLAN_FIRST; + ts->results = xmalloc(ts->count * sizeof(enum test_status)); + for (i = 0; i < ts->count; i++) + ts->results[i] = TEST_INVALID; + } else if (ts->plan == PLAN_PENDING) { + if ((unsigned long) n < ts->count) { + printf("ABORTED (invalid test number %lu)\n", ts->count); + ts->aborted = 1; + ts->reported = 1; + return 0; + } + ts->count = n; + if ((unsigned long) n > ts->allocated) { + ts->results = xrealloc(ts->results, n * sizeof(enum test_status)); + for (i = ts->allocated; i < ts->count; i++) + ts->results[i] = TEST_INVALID; + ts->allocated = n; + } + ts->plan = PLAN_FINAL; + } + return 1; +} + + +/* * Given a single line of output from a test, parse it and return the success * status of that test. Anything printed to stdout not matching the form * /^(not )?ok \d+/ is ignored. Sets ts->current to the test number that just @@ -366,20 +435,21 @@ test_checkline(const char *line, struct testset *ts) enum test_status status = TEST_PASS; const char *bail; char *end; - int current; + long number; + unsigned long i, 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; + size_t length; length = strlen(bail); if (bail[length - 1] == '\n') length--; test_backspace(ts); - printf("ABORTED (%.*s)\n", length, bail); + printf("ABORTED (%.*s)\n", (int) length, bail); ts->reported = 1; } ts->aborted = 1; @@ -393,6 +463,26 @@ test_checkline(const char *line, struct testset *ts) if (line[strlen(line) - 1] != '\n') return; + /* If the line begins with a hash mark, ignore it. */ + if (line[0] == '#') + return; + + /* If we haven't yet seen a plan, look for one. */ + if (ts->plan == PLAN_INIT && isdigit((unsigned char)(*line))) { + if (!test_plan(line, ts)) + return; + } else if (strncmp(line, "1..", 3) == 0) { + if (ts->plan == PLAN_PENDING) { + if (!test_plan(line, ts)) + return; + } else { + puts("ABORTED (multiple plans)"); + ts->aborted = 1; + ts->reported = 1; + return; + } + } + /* Parse the line, ignoring something we can't parse. */ if (strncmp(line, "not ", 4) == 0) { status = TEST_FAIL; @@ -402,17 +492,36 @@ test_checkline(const char *line, struct testset *ts) return; line = skip_whitespace(line + 2); errno = 0; - current = strtol(line, &end, 10); + number = strtol(line, &end, 10); if (errno != 0 || end == line) - current = ts->current + 1; - if (current <= 0 || current > ts->count) { + number = ts->current + 1; + current = number; + if (number <= 0 || (current > ts->count && ts->plan == PLAN_FIRST)) { test_backspace(ts); - printf("ABORTED (invalid test number %d)\n", current); + printf("ABORTED (invalid test number %lu)\n", current); ts->aborted = 1; ts->reported = 1; return; } + /* We have a valid test result. Tweak the results array if needed. */ + if (ts->plan == PLAN_INIT || ts->plan == PLAN_PENDING) { + ts->plan = PLAN_PENDING; + if (current > ts->count) + ts->count = current; + if (current > ts->allocated) { + unsigned long n; + + n = (ts->allocated == 0) ? 32 : ts->allocated * 2; + if (n < current) + n = current; + ts->results = xrealloc(ts->results, n * sizeof(enum test_status)); + for (i = ts->allocated; i < n; i++) + ts->results[i] = TEST_INVALID; + ts->allocated = n; + } + } + /* * Handle directives. We should probably do something more interesting * with unexpected passes of todo tests. @@ -431,7 +540,7 @@ test_checkline(const char *line, struct testset *ts) /* Make sure that the test number is in range and not a duplicate. */ if (ts->results[current - 1] != TEST_INVALID) { test_backspace(ts); - printf("ABORTED (duplicate test number %d)\n", current); + printf("ABORTED (duplicate test number %lu)\n", current); ts->aborted = 1; ts->reported = 1; return; @@ -442,13 +551,13 @@ test_checkline(const char *line, struct testset *ts) case TEST_PASS: ts->passed++; break; case TEST_FAIL: ts->failed++; break; case TEST_SKIP: ts->skipped++; break; - default: break; + case TEST_INVALID: break; } ts->current = current; ts->results[current - 1] = status; test_backspace(ts); if (isatty(STDOUT_FILENO)) { - ts->length = printf("%d/%d", current, ts->count); + ts->length = printf("%lu/%lu", current, ts->count); fflush(stdout); } } @@ -461,12 +570,13 @@ test_checkline(const char *line, struct testset *ts) * chars plus the space needed would go over the limit (use a limit of 0 to * disable this. */ -static int -test_print_range(int first, int last, int chars, int limit) +static unsigned int +test_print_range(unsigned long first, unsigned long last, unsigned int chars, + unsigned int limit) { - int needed = 0; - int out = 0; - int n; + unsigned int needed = 0; + unsigned int out = 0; + unsigned long n; if (chars > 0) { needed += 2; @@ -484,8 +594,8 @@ test_print_range(int first, int last, int chars, int limit) out += printf("..."); } else { if (last > first) - out += printf("%d-", first); - out += printf("%d", last); + out += printf("%lu-", first); + out += printf("%lu", last); } return out; } @@ -500,16 +610,16 @@ test_print_range(int first, int last, int chars, int limit) static void test_summarize(struct testset *ts, int status) { - int i; - int missing = 0; - int failed = 0; - int first = 0; - int last = 0; + unsigned long i; + unsigned long missing = 0; + unsigned long failed = 0; + unsigned long first = 0; + unsigned long last = 0; if (ts->aborted) { fputs("ABORTED", stdout); if (ts->count > 0) - printf(" (passed %d/%d)", ts->passed, ts->count - ts->skipped); + printf(" (passed %lu/%lu)", ts->passed, ts->count - ts->skipped); } else { for (i = 0; i < ts->count; i++) { if (ts->results[i] == TEST_INVALID) { @@ -553,9 +663,9 @@ test_summarize(struct testset *ts, int status) fputs(!status ? "ok" : "dubious", stdout); if (ts->skipped > 0) { if (ts->skipped == 1) - printf(" (skipped %d test)", ts->skipped); + printf(" (skipped %lu test)", ts->skipped); else - printf(" (skipped %d tests)", ts->skipped); + printf(" (skipped %lu tests)", ts->skipped); } } } @@ -570,8 +680,9 @@ test_summarize(struct testset *ts, int status) /* * Given a test set, analyze the results, classify the exit status, handle a - * few special error messages, and then pass it along to test_summarize() - * for the regular output. + * few special error messages, and then pass it along to test_summarize() for + * the regular output. Returns true if the test set ran successfully and all + * tests passed or were skipped, false otherwise. */ static int test_analyze(struct testset *ts) @@ -606,6 +717,10 @@ test_analyze(struct testset *ts) } else if (WIFSIGNALED(ts->status)) { test_summarize(ts, -WTERMSIG(ts->status)); return 0; + } else if (ts->plan != PLAN_FIRST && ts->plan != PLAN_FINAL) { + puts("ABORTED (no valid test plan)"); + ts->aborted = 1; + return 0; } else { test_summarize(ts, 0); return (ts->failed == 0); @@ -622,14 +737,12 @@ static int test_run(struct testset *ts) { pid_t testpid, child; - int outfd, i, status; + int outfd, status; + unsigned long i; FILE *output; char buffer[BUFSIZ]; - /* - * Initialize the test and our data structures, flagging this set in error - * if the initialization fails. - */ + /* Run the test program. */ testpid = test_start(ts->path, &outfd); output = fdopen(outfd, "r"); if (!output) { @@ -637,15 +750,11 @@ test_run(struct testset *ts) fflush(stdout); sysdie("fdopen failed"); } - if (!fgets(buffer, sizeof(buffer), output)) - ts->aborted = 1; - 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)) test_checkline(buffer, ts); - if (ferror(output)) + if (ferror(output) || ts->plan == PLAN_INIT) ts->aborted = 1; test_backspace(ts); @@ -686,7 +795,8 @@ static void test_fail_summary(const struct testlist *fails) { struct testset *ts; - int i, chars, total, first, last; + unsigned int chars; + unsigned long i, first, last, total; puts(header); @@ -695,7 +805,7 @@ test_fail_summary(const struct testlist *fails) for (; fails; fails = fails->next) { ts = fails->ts; total = ts->count - ts->skipped; - printf("%-26.26s %4d/%-4d %3.0f%% %4d ", ts->file, ts->failed, + printf("%-26.26s %4lu/%-4lu %3.0f%% %4lu ", ts->file, ts->failed, total, total ? (ts->failed * 100.0) / total : 0, ts->skipped); if (WIFEXITED(ts->status)) @@ -711,19 +821,25 @@ test_fail_summary(const struct testlist *fails) last = 0; for (i = 0; i < ts->count; i++) { if (ts->results[i] == TEST_FAIL) { - if (first && i == last) + if (first != 0 && i == last) last = i + 1; else { - if (first) + if (first != 0) chars += test_print_range(first, last, chars, 20); first = i + 1; last = i + 1; } } } - if (first) + if (first != 0) test_print_range(first, last, chars, 20); putchar('\n'); + free(ts->file); + free(ts->path); + free(ts->results); + if (ts->reason != NULL) + free(ts->reason); + free(ts); } } @@ -746,7 +862,7 @@ find_test(const char *name, struct testset *ts, const char *source, { char *path; const char *bases[] = { ".", build, source, NULL }; - int i; + unsigned int i; for (i = 0; bases[i] != NULL; i++) { path = xmalloc(strlen(bases[i]) + strlen(name) + 4); @@ -778,20 +894,21 @@ static int test_batch(const char *testlist, const char *source, const char *build) { FILE *tests; - size_t length, i; - size_t longest = 0; + unsigned int length, i; + unsigned int longest = 0; char buffer[BUFSIZ]; - int line; + unsigned int line; struct testset ts, *tmp; struct timeval start, end; struct rusage stats; - struct testlist *failhead = 0; - struct testlist *failtail = 0; - int total = 0; - int passed = 0; - int skipped = 0; - int failed = 0; - int aborted = 0; + struct testlist *failhead = NULL; + struct testlist *failtail = NULL; + struct testlist *next; + unsigned long total = 0; + unsigned long passed = 0; + unsigned long skipped = 0; + unsigned long failed = 0; + unsigned long aborted = 0; /* * Open our file of tests to run and scan it, checking for lines that @@ -805,7 +922,7 @@ test_batch(const char *testlist, const char *source, const char *build) line++; length = strlen(buffer) - 1; if (buffer[length] != '\n') { - fprintf(stderr, "%s:%d: line too long\n", testlist, line); + fprintf(stderr, "%s:%u: line too long\n", testlist, line); exit(1); } if (length > longest) @@ -834,7 +951,7 @@ test_batch(const char *testlist, const char *source, const char *build) line++; length = strlen(buffer) - 1; if (buffer[length] != '\n') { - fprintf(stderr, "%s:%d: line too long\n", testlist, line); + fprintf(stderr, "%s:%u: line too long\n", testlist, line); exit(1); } buffer[length] = '\0'; @@ -844,12 +961,14 @@ test_batch(const char *testlist, const char *source, const char *build) if (isatty(STDOUT_FILENO)) fflush(stdout); memset(&ts, 0, sizeof(ts)); + ts.plan = PLAN_INIT; ts.file = xstrdup(buffer); find_test(buffer, &ts, source, build); ts.reason = NULL; if (test_run(&ts)) { free(ts.file); free(ts.path); + free(ts.results); if (ts.reason != NULL) free(ts.reason); } else { @@ -858,13 +977,13 @@ test_batch(const char *testlist, const char *source, const char *build) if (!failhead) { failhead = xmalloc(sizeof(struct testset)); failhead->ts = tmp; - failhead->next = 0; + failhead->next = NULL; failtail = failhead; } else { failtail->next = xmalloc(sizeof(struct testset)); failtail = failtail->next; failtail->ts = tmp; - failtail->next = 0; + failtail->next = NULL; } } aborted += ts.aborted; @@ -880,29 +999,35 @@ test_batch(const char *testlist, const char *source, const char *build) getrusage(RUSAGE_CHILDREN, &stats); /* Print out our final results. */ - if (failhead) + if (failhead != NULL) { test_fail_summary(failhead); + while (failhead != NULL) { + next = failhead->next; + free(failhead); + failhead = next; + } + } putchar('\n'); if (aborted != 0) { if (aborted == 1) - printf("Aborted %d test set", aborted); + printf("Aborted %lu test set", aborted); else - printf("Aborted %d test sets", aborted); - printf(", passed %d/%d tests", passed, total); + printf("Aborted %lu test sets", aborted); + printf(", passed %lu/%lu tests", passed, total); } else if (failed == 0) fputs("All tests successful", stdout); else - printf("Failed %d/%d tests, %.2f%% okay", failed, total, + printf("Failed %lu/%lu tests, %.2f%% okay", failed, total, (total - failed) * 100.0 / total); if (skipped != 0) { if (skipped == 1) - printf(", %d test skipped", skipped); + printf(", %lu test skipped", skipped); else - printf(", %d tests skipped", skipped); + printf(", %lu tests skipped", skipped); } puts("."); - printf("Files=%d, Tests=%d", line, total); + printf("Files=%u, Tests=%lu", line, total); printf(", %.2f seconds", tv_diff(&end, &start)); printf(" (%.2f usr + %.2f sys = %.2f CPU)\n", tv_seconds(&stats.ru_utime), tv_seconds(&stats.ru_stime), diff --git a/tests/server/backend-t b/tests/server/backend-t index b58d02c..a618391 100755 --- a/tests/server/backend-t +++ b/tests/server/backend-t @@ -289,11 +289,19 @@ for my $command (sort keys %acl_commands) { my @args = @base; $args[$arg] = 'foo;bar'; ($out, $err) = run_backend ('acl', $command, @args); - is ($err, "invalid characters in argument: foo;bar\n", - "Invalid arguments for acl $command $arg"); - is ($OUTPUT, "error for admin (1.2.3.4): invalid characters in" - . " argument: foo;bar\n", ' and syslog correct'); - is ($out, "$new\n", ' and nothing ran'); + if (($command eq 'add' or $command eq 'remove') and $arg == 2) { + is ($err, '', 'Add/remove allows any characters'); + is ($OUTPUT, "command acl $command @args[0..2] from admin" + . " (1.2.3.4) succeeded\n", ' and success logged'); + is ($out, "$new\nacl_$command @args[0..2]\n", + ' and calls the right method'); + } else { + is ($err, "invalid characters in argument: foo;bar\n", + "Invalid arguments for acl $command $arg"); + is ($OUTPUT, "error for admin (1.2.3.4): invalid characters in" + . " argument: foo;bar\n", ' and syslog correct'); + is ($out, "$new\n", ' and nothing ran'); + } } } for my $command (sort keys %flag_commands) { diff --git a/tests/server/report-t b/tests/server/report-t index 394a869..0771946 100755 --- a/tests/server/report-t +++ b/tests/server/report-t @@ -8,7 +8,7 @@ # See LICENSE for licensing terms. use strict; -use Test::More tests => 44; +use Test::More tests => 48; # Create a dummy class for Wallet::Report that prints what method was called # with its arguments and returns data for testing. @@ -35,6 +35,7 @@ sub acls { shift; print "acls @_\n"; return if ($error or $empty); + return ([ qw/d1 d2 d3/ ], [ qw/o1 o2/ ]) if (@_ && $_[0] eq 'duplicate'); return ([ 1, 'ADMIN' ], [ 2, 'group/admins' ], [ 4, 'group/users' ]); } @@ -119,6 +120,10 @@ 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', 'duplicate'); +is ($err, '', 'Duplicate report succeeds for ACLs'); +is ($out, "new\nacls duplicate\nd1 d2 d3\no1 o2\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" @@ -168,6 +173,9 @@ $Wallet::Report::empty = 1; ($out, $err) = run_report ('acls'); is ($err, '', 'acls runs with an empty list and no errors'); is ($out, "new\nacls \n", ' and calls the right methods'); +($out, $err) = run_report ('acls', 'duplicate'); +is ($err, '', 'acls duplicate runs with an empty list and no errors'); +is ($out, "new\nacls duplicate\n", ' and calls the right methods'); ($out, $err) = run_report ('audit', 'objects', 'name'); is ($err, '', 'audit runs with an empty list and no errors'); is ($out, "new\naudit objects name\n", ' and calls the right methods'); diff --git a/tests/tap/basic.c b/tests/tap/basic.c index 5ca9ff4..829f91a 100644 --- a/tests/tap/basic.c +++ b/tests/tap/basic.c @@ -2,12 +2,13 @@ * 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 + * of the form ok() or is*() 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. + * utility routines help in constructing more complex tests, skipping tests, + * or setting up the TAP output format. * - * Copyright 2009 Russ Allbery <rra@stanford.edu> + * Copyright 2009, 2010 Russ Allbery <rra@stanford.edu> * Copyright 2006, 2007, 2008 * Board of Trustees, Leland Stanford Jr. University * Copyright (c) 2004, 2005, 2006 @@ -34,7 +35,7 @@ * The test count. Always contains the number that will be used for the next * test status. */ -int testnum = 1; +unsigned long testnum = 1; /* * Status information stored so that we can give a test summary at the end of @@ -44,10 +45,14 @@ int testnum = 1; * 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. + * + * If _lazy is true, we're doing lazy planning and will print out the plan + * based on the last test number at the end of testing. */ -static int _planned = 0; -static int _failed = 0; +static unsigned long _planned = 0; +static unsigned long _failed = 0; static pid_t _process = 0; +static int _lazy = 0; /* @@ -57,22 +62,28 @@ static pid_t _process = 0; static void finish(void) { - int highest = testnum - 1; - - if (_process != 0 && getpid() == _process && _planned > 0) { + unsigned long highest = testnum - 1; + + if (_planned == 0 && !_lazy) + return; + if (_process != 0 && getpid() == _process) { + if (_lazy) { + printf("1..%lu\n", highest); + _planned = highest; + } if (_planned > highest) - printf("# Looks like you planned %d test%s but only ran %d\n", + printf("# Looks like you planned %lu test%s but only ran %lu\n", _planned, (_planned > 1 ? "s" : ""), highest); else if (_planned < highest) - printf("# Looks like you planned %d test%s but ran %d extra\n", + printf("# Looks like you planned %lu test%s but ran %lu extra\n", _planned, (_planned > 1 ? "s" : ""), highest - _planned); else if (_failed > 0) - printf("# Looks like you failed %d test%s of %d\n", _failed, + printf("# Looks like you failed %lu test%s of %lu\n", _failed, (_failed > 1 ? "s" : ""), _planned); else if (_planned > 1) - printf("# All %d tests successful or skipped\n", _planned); + printf("# All %lu tests successful or skipped\n", _planned); else - printf("# %d test successful or skipped\n", _planned); + printf("# %lu test successful or skipped\n", _planned); } } @@ -82,12 +93,12 @@ finish(void) * the number of tests in the test suite. */ void -plan(int count) +plan(unsigned long 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); + printf("1..%lu\n", count); testnum = 1; _planned = count; _process = getpid(); @@ -96,6 +107,23 @@ plan(int count) /* + * Initialize things for lazy planning, where we'll automatically print out a + * plan at the end of the program. Turns on line buffering on stdout as well. + */ +void +plan_lazy(void) +{ + if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0) + fprintf(stderr, "# cannot set stdout to line buffered: %s\n", + strerror(errno)); + testnum = 1; + _process = getpid(); + _lazy = 1; + 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. */ @@ -134,7 +162,7 @@ print_desc(const char *format, va_list args) void ok(int success, const char *format, ...) { - printf("%sok %d", success ? "" : "not ", testnum++); + printf("%sok %lu", success ? "" : "not ", testnum++); if (!success) _failed++; if (format != NULL) { @@ -149,12 +177,27 @@ ok(int success, const char *format, ...) /* + * Same as ok(), but takes the format arguments as a va_list. + */ +void +okv(int success, const char *format, va_list args) +{ + printf("%sok %lu", success ? "" : "not ", testnum++); + if (!success) + _failed++; + if (format != NULL) + print_desc(format, args); + putchar('\n'); +} + + +/* * Skip a test. */ void skip(const char *reason, ...) { - printf("ok %d # skip", testnum++); + printf("ok %lu # skip", testnum++); if (reason != NULL) { va_list args; @@ -171,12 +214,12 @@ skip(const char *reason, ...) * Report the same status on the next count tests. */ void -ok_block(int count, int status, const char *format, ...) +ok_block(unsigned long count, int status, const char *format, ...) { - int i; + unsigned long i; for (i = 0; i < count; i++) { - printf("%sok %d", status ? "" : "not ", testnum++); + printf("%sok %lu", status ? "" : "not ", testnum++); if (!status) _failed++; if (format != NULL) { @@ -195,12 +238,12 @@ ok_block(int count, int status, const char *format, ...) * Skip the next count tests. */ void -skip_block(int count, const char *reason, ...) +skip_block(unsigned long count, const char *reason, ...) { - int i; + unsigned long i; for (i = 0; i < count; i++) { - printf("ok %d # skip", testnum++); + printf("ok %lu # skip", testnum++); if (reason != NULL) { va_list args; @@ -219,13 +262,13 @@ skip_block(int count, const char *reason, ...) * if those two numbers match. */ void -is_int(int wanted, int seen, const char *format, ...) +is_int(long wanted, long seen, const char *format, ...) { if (wanted == seen) - printf("ok %d", testnum++); + printf("ok %lu", testnum++); else { - printf("# wanted: %d\n# seen: %d\n", wanted, seen); - printf("not ok %d", testnum++); + printf("# wanted: %ld\n# seen: %ld\n", wanted, seen); + printf("not ok %lu", testnum++); _failed++; } if (format != NULL) { @@ -251,10 +294,10 @@ is_string(const char *wanted, const char *seen, const char *format, ...) if (seen == NULL) seen = "(null)"; if (strcmp(wanted, seen) == 0) - printf("ok %d", testnum++); + printf("ok %lu", testnum++); else { printf("# wanted: %s\n# seen: %s\n", wanted, seen); - printf("not ok %d", testnum++); + printf("not ok %lu", testnum++); _failed++; } if (format != NULL) { @@ -276,10 +319,10 @@ void is_double(double wanted, double seen, const char *format, ...) { if (wanted == seen) - printf("ok %d", testnum++); + printf("ok %lu", testnum++); else { printf("# wanted: %g\n# seen: %g\n", wanted, seen); - printf("not ok %d", testnum++); + printf("not ok %lu", testnum++); _failed++; } if (format != NULL) { @@ -301,11 +344,11 @@ void is_hex(unsigned long wanted, unsigned long seen, const char *format, ...) { if (wanted == seen) - printf("ok %d", testnum++); + printf("ok %lu", testnum++); else { printf("# wanted: %lx\n# seen: %lx\n", (unsigned long) wanted, (unsigned long) seen); - printf("not ok %d", testnum++); + printf("not ok %lu", testnum++); _failed++; } if (format != NULL) { @@ -354,3 +397,88 @@ sysbail(const char *format, ...) printf(": %s\n", strerror(oerrno)); exit(1); } + + +/* + * Report a diagnostic to stderr. + */ +void +diag(const char *format, ...) +{ + va_list args; + + fflush(stdout); + printf("# "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); +} + + +/* + * Report a diagnostic to stderr, appending strerror(errno). + */ +void +sysdiag(const char *format, ...) +{ + va_list args; + int oerrno = errno; + + fflush(stdout); + printf("# "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf(": %s\n", strerror(oerrno)); +} + + +/* + * Locate a test file. Given the partial path to a file, look under BUILD and + * then SOURCE for the file and return the full path to the file. Returns + * NULL if the file doesn't exist. A non-NULL return should be freed with + * test_file_path_free(). + * + * This function uses sprintf because it attempts to be independent of all + * other portability layers. The use immediately after a memory allocation + * should be safe without using snprintf or strlcpy/strlcat. + */ +char * +test_file_path(const char *file) +{ + char *base; + char *path = NULL; + size_t length; + const char *envs[] = { "BUILD", "SOURCE", NULL }; + int i; + + for (i = 0; envs[i] != NULL; i++) { + base = getenv(envs[i]); + if (base == NULL) + continue; + length = strlen(base) + 1 + strlen(file) + 1; + path = malloc(length); + if (path == NULL) + sysbail("cannot allocate memory"); + sprintf(path, "%s/%s", base, file); + if (access(path, R_OK) == 0) + break; + free(path); + path = NULL; + } + return path; +} + + +/* + * Free a path returned from test_file_path(). This function exists primarily + * for Windows, where memory must be freed from the same library domain that + * it was allocated from. + */ +void +test_file_path_free(char *path) +{ + if (path != NULL) + free(path); +} diff --git a/tests/tap/basic.h b/tests/tap/basic.h index efe94ba..9602db4 100644 --- a/tests/tap/basic.h +++ b/tests/tap/basic.h @@ -1,6 +1,7 @@ /* * Basic utility routines for the TAP protocol. * + * Copyright 2009, 2010 Russ Allbery <rra@stanford.edu> * Copyright 2006, 2007, 2008 * Board of Trustees, Leland Stanford Jr. University * Copyright (c) 2004, 2005, 2006 @@ -14,6 +15,7 @@ #ifndef TAP_BASIC_H #define TAP_BASIC_H 1 +#include <stdarg.h> /* va_list */ #include <sys/types.h> /* pid_t */ /* @@ -56,29 +58,40 @@ BEGIN_DECLS * The test count. Always contains the number that will be used for the next * test status. */ -extern int testnum; +extern unsigned long testnum; /* Print out the number of tests and set standard output to line buffered. */ -void plan(int count); +void plan(unsigned long count); + +/* + * Prepare for lazy planning, in which the plan will be printed automatically + * at the end of the test program. + */ +void plan_lazy(void); /* Skip the entire test suite. Call instead of plan. */ void skip_all(const char *format, ...) __attribute__((__noreturn__, __format__(printf, 1, 2))); -/* Basic reporting functions. */ +/* + * Basic reporting functions. The okv() function is the same as ok() but + * takes the test description as a va_list to make it easier to reuse the + * reporting infrastructure when writing new tests. + */ void ok(int success, const char *format, ...) __attribute__((__format__(printf, 2, 3))); +void okv(int success, const char *format, va_list args); 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, ...) +void ok_block(unsigned long count, int success, const char *format, ...) __attribute__((__format__(printf, 3, 4))); -void skip_block(int count, const char *reason, ...) +void skip_block(unsigned long 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, ...) +void is_int(long wanted, long seen, const char *format, ...) __attribute__((__format__(printf, 3, 4))); void is_double(double wanted, double seen, const char *format, ...) __attribute__((__format__(printf, 3, 4))); @@ -93,6 +106,20 @@ void bail(const char *format, ...) void sysbail(const char *format, ...) __attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2))); +/* Report a diagnostic to stderr prefixed with #. */ +void diag(const char *format, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); +void sysdiag(const char *format, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); + +/* + * Find a test file under BUILD or SOURCE, returning the full path. The + * returned path should be freed with test_file_path_free(). + */ +char *test_file_path(const char *file) + __attribute__((__malloc__, __nonnull__)); +void test_file_path_free(char *path); + END_DECLS -#endif /* LIBTEST_H */ +#endif /* TAP_BASIC_H */ diff --git a/tests/tap/kerberos.c b/tests/tap/kerberos.c index 700212e..a17d980 100644 --- a/tests/tap/kerberos.c +++ b/tests/tap/kerberos.c @@ -23,33 +23,6 @@ /* - * 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. @@ -78,7 +51,7 @@ kerberos_setup(void) krb5_creds creds; /* Read the principal name and find the keytab file. */ - path = find_file("data/test.principal"); + path = test_file_path("data/test.principal"); if (path == NULL) return NULL; file = fopen(path, "r"); @@ -95,7 +68,7 @@ kerberos_setup(void) bail("no newline in %s", path); free(path); principal[strlen(principal) - 1] = '\0'; - path = find_file("data/test.keytab"); + path = test_file_path("data/test.keytab"); if (path == NULL) return NULL; diff --git a/tests/tap/kerberos.sh b/tests/tap/kerberos.sh index da07e66..904cae5 100644 --- a/tests/tap/kerberos.sh +++ b/tests/tap/kerberos.sh @@ -1,7 +1,7 @@ # Shell function library to initialize Kerberos credentials # # Written by Russ Allbery <rra@stanford.edu> -# Copyright 2009 Board of Trustees, Leland Stanford Jr. University +# Copyright 2009, 2010 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -10,18 +10,9 @@ # 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 + keytab=`test_file_path data/test.keytab` + principal=`test_file_path data/test.principal` + principal=`cat "$principal" 2>/dev/null` if [ -z "$keytab" ] || [ -z "$principal" ] ; then return 1 fi @@ -46,3 +37,18 @@ kerberos_setup () { kerberos_cleanup () { rm -f "$BUILD/data/test.cache" } + +# List the contents of a keytab with enctypes and keys. This adjusts for the +# difference between MIT Kerberos (which uses klist) and Heimdal (which uses +# ktutil). Be careful to try klist first, since the ktutil on MIT Kerberos +# may just hang. Takes the keytab to list and the file into which to save the +# output, and strips off the header containing the file name. +ktutil_list () { + if klist -keK "$1" > ktutil-tmp 2>/dev/null ; then + : + else + ktutil -k "$1" list --keys > ktutil-tmp < /dev/null 2>/dev/null + fi + sed -e '/Keytab name:/d' -e "/^[^ ]*:/d" ktutil-tmp > "$2" + rm -f ktutil-tmp +} diff --git a/tests/tap/libtap.sh b/tests/tap/libtap.sh index 1846840..a9b46d4 100644 --- a/tests/tap/libtap.sh +++ b/tests/tap/libtap.sh @@ -1,7 +1,7 @@ # Shell function library for test cases. # # Written by Russ Allbery <rra@stanford.edu> -# Copyright 2009 Russ Allbery <rra@stanford.edu> +# Copyright 2009, 2010 Russ Allbery <rra@stanford.edu> # Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University # # See LICENSE for licensing terms. @@ -15,10 +15,22 @@ plan () { trap finish 0 } +# Prepare for lazy planning. +plan_lazy () { + count=1 + planned=0 + failed=0 + trap finish 0 +} + # Report the test status on exit. finish () { local highest looks highest=`expr "$count" - 1` + if [ "$planned" = 0 ] ; then + echo "1..$highest" + planned="$highest" + fi looks='# Looks like you' if [ "$planned" -gt 0 ] ; then if [ "$planned" -gt "$highest" ] ; then @@ -146,3 +158,21 @@ bail () { echo 'Bail out!' "$@" exit 1 } + +# Output a diagnostic on standard error, preceded by the required # mark. +diag () { + echo '#' "$@" +} + +# Search for the given file first in $BUILD and then in $SOURCE and echo the +# path where the file was found, or the empty string if the file wasn't +# found. +test_file_path () { + if [ -f "$BUILD/$1" ] ; then + echo "$BUILD/$1" + elif [ -f "$SOURCE/$1" ] ; then + echo "$SOURCE/$1" + else + echo '' + fi +} diff --git a/tests/tap/remctl.sh b/tests/tap/remctl.sh index b9667ef..9e01bcf 100644 --- a/tests/tap/remctl.sh +++ b/tests/tap/remctl.sh @@ -10,18 +10,12 @@ 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 + keytab=`test_file_path data/test.keytab` + principal=`test_file_path data/test.principal` + principal=`cat "$principal" 2>/dev/null` + if [ -z "$keytab" ] || [ -z "$principal" ] ; then + return 1 + fi 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 \ diff --git a/tests/util/messages-t.c b/tests/util/messages-t.c index fb82a42..a58f82c 100644 --- a/tests/util/messages-t.c +++ b/tests/util/messages-t.c @@ -146,8 +146,8 @@ test_strerror(int status, const char *output, int error, char *full_output, *name; full_output = concat(output, ": ", strerror(error), "\n", (char *) NULL); - xasprintf(&name, "strerror %d", testnum / 3 + 1); - is_function_output(function, status, full_output, name); + xasprintf(&name, "strerror %lu", testnum / 3 + 1); + is_function_output(function, status, full_output, "%s", name); free(full_output); free(name); } diff --git a/tests/util/xmalloc.c b/tests/util/xmalloc.c index 3bd5588..b6f4564 100644 --- a/tests/util/xmalloc.c +++ b/tests/util/xmalloc.c @@ -246,8 +246,6 @@ main(int argc, char *argv[]) size_t limit = 0; int willfail = 0; unsigned char code; - struct rlimit rl; - void *tmp; if (argc < 3) die("Usage error. Type, size, and limit must be given."); @@ -290,6 +288,9 @@ main(int argc, char *argv[]) */ if (limit > 0) { #if HAVE_SETRLIMIT && defined(RLIMIT_AS) + struct rlimit rl; + void *tmp; + rl.rlim_cur = limit; rl.rlim_max = limit; if (setrlimit(RLIMIT_AS, &rl) < 0) { diff --git a/util/macros.h b/util/macros.h index 97b2c2b..0104d9f 100644 --- a/util/macros.h +++ b/util/macros.h @@ -8,7 +8,6 @@ #ifndef UTIL_MACROS_H #define UTIL_MACROS_H 1 -#include <config.h> #include <portable/macros.h> /* Used for unused parameters to silence gcc warnings. */ diff --git a/util/messages.c b/util/messages.c index ef920b2..3592692 100644 --- a/util/messages.c +++ b/util/messages.c @@ -107,9 +107,9 @@ const char *message_program_name = NULL; * handler list, the count of handlers, and the argument list. */ static void -message_handlers(message_handler_func **list, int count, va_list args) +message_handlers(message_handler_func **list, unsigned int count, va_list args) { - int i; + unsigned int i; if (*list != stdout_handlers && *list != stderr_handlers) free(*list); @@ -127,7 +127,7 @@ message_handlers(message_handler_func **list, int count, va_list args) */ #define HANDLER_FUNCTION(type) \ void \ - message_handlers_ ## type(int count, ...) \ + message_handlers_ ## type(unsigned int count, ...) \ { \ va_list args; \ \ @@ -145,7 +145,7 @@ HANDLER_FUNCTION(die) * Print a message to stdout, supporting message_program_name. */ void -message_log_stdout(int len UNUSED, const char *fmt, va_list args, int err) +message_log_stdout(size_t len UNUSED, const char *fmt, va_list args, int err) { if (message_program_name != NULL) fprintf(stdout, "%s: ", message_program_name); @@ -162,7 +162,7 @@ message_log_stdout(int len UNUSED, const char *fmt, va_list args, int err) * stdout so that errors and regular output occur in the right order. */ void -message_log_stderr(int len UNUSED, const char *fmt, va_list args, int err) +message_log_stderr(size_t len UNUSED, const char *fmt, va_list args, int err) { fflush(stdout); if (message_program_name != NULL) @@ -183,7 +183,7 @@ message_log_stderr(int len UNUSED, const char *fmt, va_list args, int err) * log the errno information. */ static void -message_log_syslog(int pri, int len, const char *fmt, va_list args, int err) +message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err) { char *buffer; @@ -218,11 +218,11 @@ message_log_syslog(int pri, int len, const char *fmt, va_list args, int err) * Do the same sort of wrapper to generate all of the separate syslog logging * functions. */ -#define SYSLOG_FUNCTION(name, type) \ - void \ - message_log_syslog_ ## name(int l, const char *f, va_list a, int e) \ - { \ - message_log_syslog(LOG_ ## type, l, f, a, e); \ +#define SYSLOG_FUNCTION(name, type) \ + void \ + message_log_syslog_ ## name(size_t l, const char *f, va_list a, int e) \ + { \ + message_log_syslog(LOG_ ## type, l, f, a, e); \ } SYSLOG_FUNCTION(debug, DEBUG) SYSLOG_FUNCTION(info, INFO) @@ -243,7 +243,7 @@ debug(const char *format, ...) { va_list args; message_handler_func *log; - int length; + ssize_t length; if (debug_handlers == NULL) return; @@ -254,7 +254,7 @@ debug(const char *format, ...) return; for (log = debug_handlers; *log != NULL; log++) { va_start(args, format); - (**log)(length, format, args, 0); + (**log)((size_t) length, format, args, 0); va_end(args); } } @@ -264,7 +264,7 @@ notice(const char *format, ...) { va_list args; message_handler_func *log; - int length; + ssize_t length; va_start(args, format); length = vsnprintf(NULL, 0, format, args); @@ -273,7 +273,7 @@ notice(const char *format, ...) return; for (log = notice_handlers; *log != NULL; log++) { va_start(args, format); - (**log)(length, format, args, 0); + (**log)((size_t) length, format, args, 0); va_end(args); } } @@ -283,7 +283,7 @@ sysnotice(const char *format, ...) { va_list args; message_handler_func *log; - int length; + ssize_t length; int error = errno; va_start(args, format); @@ -293,7 +293,7 @@ sysnotice(const char *format, ...) return; for (log = notice_handlers; *log != NULL; log++) { va_start(args, format); - (**log)(length, format, args, error); + (**log)((size_t) length, format, args, error); va_end(args); } } @@ -303,7 +303,7 @@ warn(const char *format, ...) { va_list args; message_handler_func *log; - int length; + ssize_t length; va_start(args, format); length = vsnprintf(NULL, 0, format, args); @@ -312,7 +312,7 @@ warn(const char *format, ...) return; for (log = warn_handlers; *log != NULL; log++) { va_start(args, format); - (**log)(length, format, args, 0); + (**log)((size_t) length, format, args, 0); va_end(args); } } @@ -322,7 +322,7 @@ syswarn(const char *format, ...) { va_list args; message_handler_func *log; - int length; + ssize_t length; int error = errno; va_start(args, format); @@ -332,7 +332,7 @@ syswarn(const char *format, ...) return; for (log = warn_handlers; *log != NULL; log++) { va_start(args, format); - (**log)(length, format, args, error); + (**log)((size_t) length, format, args, error); va_end(args); } } @@ -342,7 +342,7 @@ die(const char *format, ...) { va_list args; message_handler_func *log; - int length; + ssize_t length; va_start(args, format); length = vsnprintf(NULL, 0, format, args); @@ -350,7 +350,7 @@ die(const char *format, ...) if (length >= 0) for (log = die_handlers; *log != NULL; log++) { va_start(args, format); - (**log)(length, format, args, 0); + (**log)((size_t) length, format, args, 0); va_end(args); } exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1); @@ -361,7 +361,7 @@ sysdie(const char *format, ...) { va_list args; message_handler_func *log; - int length; + ssize_t length; int error = errno; va_start(args, format); @@ -370,7 +370,7 @@ sysdie(const char *format, ...) if (length >= 0) for (log = die_handlers; *log != NULL; log++) { va_start(args, format); - (**log)(length, format, args, error); + (**log)((size_t) length, format, args, error); va_end(args); } exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1); diff --git a/util/messages.h b/util/messages.h index ff86f39..dbdb256 100644 --- a/util/messages.h +++ b/util/messages.h @@ -49,35 +49,35 @@ void sysdie(const char *, ...) * 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, ...); +void message_handlers_debug(unsigned int count, ...); +void message_handlers_notice(unsigned int count, ...); +void message_handlers_warn(unsigned int count, ...); +void message_handlers_die(unsigned 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) +void message_log_stdout(size_t, const char *, va_list, int) __attribute((__nonnull__)); -void message_log_stderr(int, const char *, va_list, int) +void message_log_stderr(size_t, const char *, va_list, int) __attribute((__nonnull__)); -void message_log_syslog_debug(int, const char *, va_list, int) +void message_log_syslog_debug(size_t, const char *, va_list, int) __attribute((__nonnull__)); -void message_log_syslog_info(int, const char *, va_list, int) +void message_log_syslog_info(size_t, const char *, va_list, int) __attribute((__nonnull__)); -void message_log_syslog_notice(int, const char *, va_list, int) +void message_log_syslog_notice(size_t, const char *, va_list, int) __attribute((__nonnull__)); -void message_log_syslog_warning(int, const char *, va_list, int) +void message_log_syslog_warning(size_t, const char *, va_list, int) __attribute((__nonnull__)); -void message_log_syslog_err(int, const char *, va_list, int) +void message_log_syslog_err(size_t, const char *, va_list, int) __attribute((__nonnull__)); -void message_log_syslog_crit(int, const char *, va_list, int) +void message_log_syslog_crit(size_t, const char *, va_list, int) __attribute((__nonnull__)); /* The type of a message handler. */ -typedef void (*message_handler_func)(int, const char *, va_list, int); +typedef void (*message_handler_func)(size_t, const char *, va_list, int); /* If non-NULL, called before exit and its return value passed to exit. */ extern int (*message_fatal_cleanup)(void); |