summaryrefslogtreecommitdiffstats
path: root/third_party/heimdal/tests
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/heimdal/tests')
-rw-r--r--third_party/heimdal/tests/ChangeLog793
-rw-r--r--third_party/heimdal/tests/Makefile.am13
-rw-r--r--third_party/heimdal/tests/NTMakefile35
-rw-r--r--third_party/heimdal/tests/bin/Makefile.am30
-rw-r--r--third_party/heimdal/tests/bin/intr.c56
-rw-r--r--third_party/heimdal/tests/bin/setup-env.in89
-rw-r--r--third_party/heimdal/tests/can/Makefile.am58
-rw-r--r--third_party/heimdal/tests/can/NTMakefile35
-rw-r--r--third_party/heimdal/tests/can/apple-10.4.kadm4
-rw-r--r--third_party/heimdal/tests/can/apple-10.4.reqbin0 -> 1199 bytes
-rw-r--r--third_party/heimdal/tests/can/check-can.in66
-rw-r--r--third_party/heimdal/tests/can/heim-0.8.kadm4
-rw-r--r--third_party/heimdal/tests/can/heim-0.8.reqbin0 -> 1177 bytes
-rw-r--r--third_party/heimdal/tests/can/krb5.conf.in29
-rw-r--r--third_party/heimdal/tests/can/mit-pkinit-20070607.ca.crt23
-rw-r--r--third_party/heimdal/tests/can/mit-pkinit-20070607.kadm3
-rw-r--r--third_party/heimdal/tests/can/mit-pkinit-20070607.reqbin0 -> 2352 bytes
-rw-r--r--third_party/heimdal/tests/can/mit-pkinit-20070607.xf31
-rw-r--r--third_party/heimdal/tests/can/test_can.in79
-rw-r--r--third_party/heimdal/tests/db/Makefile.am103
-rw-r--r--third_party/heimdal/tests/db/NTMakefile35
-rw-r--r--third_party/heimdal/tests/db/add-modify-delete.in140
-rw-r--r--third_party/heimdal/tests/db/check-aliases.in134
-rw-r--r--third_party/heimdal/tests/db/check-dbinfo.in52
-rw-r--r--third_party/heimdal/tests/db/have-db.in72
-rw-r--r--third_party/heimdal/tests/db/krb5-mit.conf.in18
-rw-r--r--third_party/heimdal/tests/db/krb5.conf.in32
-rw-r--r--third_party/heimdal/tests/db/loaddump-db.in134
-rw-r--r--third_party/heimdal/tests/db/text-dump-0.77
-rw-r--r--third_party/heimdal/tests/db/text-dump-known-ext7
-rw-r--r--third_party/heimdal/tests/db/text-dump-no-ext7
-rw-r--r--third_party/heimdal/tests/db/text-dump-unknown-ext7
-rw-r--r--third_party/heimdal/tests/gss/Makefile.am103
-rw-r--r--third_party/heimdal/tests/gss/NTMakefile35
-rw-r--r--third_party/heimdal/tests/gss/check-basic.in219
-rw-r--r--third_party/heimdal/tests/gss/check-context.in582
-rw-r--r--third_party/heimdal/tests/gss/check-gss.in50
-rw-r--r--third_party/heimdal/tests/gss/check-gssmask.in137
-rw-r--r--third_party/heimdal/tests/gss/check-negoex.in278
-rw-r--r--third_party/heimdal/tests/gss/check-ntlm.in168
-rw-r--r--third_party/heimdal/tests/gss/check-spnego.in246
-rw-r--r--third_party/heimdal/tests/gss/include-krb5.conf17
-rw-r--r--third_party/heimdal/tests/gss/krb5.conf.in54
-rw-r--r--third_party/heimdal/tests/gss/mech.in5
-rw-r--r--third_party/heimdal/tests/gss/new_clients_k5.conf.in5
-rw-r--r--third_party/heimdal/tests/gss/ntlm-user-file.txt2
-rw-r--r--third_party/heimdal/tests/java/KerberosInit.java95
-rw-r--r--third_party/heimdal/tests/java/Makefile.am46
-rw-r--r--third_party/heimdal/tests/java/NTMakefile35
-rw-r--r--third_party/heimdal/tests/java/check-kinit.in147
-rw-r--r--third_party/heimdal/tests/java/have-java.sh58
-rw-r--r--third_party/heimdal/tests/java/jaas.conf14
-rw-r--r--third_party/heimdal/tests/java/krb5.conf.in32
-rw-r--r--third_party/heimdal/tests/kdc/Makefile.am443
-rw-r--r--third_party/heimdal/tests/kdc/NTMakefile35
-rw-r--r--third_party/heimdal/tests/kdc/an2ln-db.txt144
-rw-r--r--third_party/heimdal/tests/kdc/check-authz.in134
-rw-r--r--third_party/heimdal/tests/kdc/check-bx509.in1127
-rw-r--r--third_party/heimdal/tests/kdc/check-canon.in210
-rw-r--r--third_party/heimdal/tests/kdc/check-cc.in203
-rw-r--r--third_party/heimdal/tests/kdc/check-delegation.in152
-rw-r--r--third_party/heimdal/tests/kdc/check-des.in155
-rw-r--r--third_party/heimdal/tests/kdc/check-digest.in291
-rw-r--r--third_party/heimdal/tests/kdc/check-fast.in212
-rw-r--r--third_party/heimdal/tests/kdc/check-hdb-mitdb.in111
-rw-r--r--third_party/heimdal/tests/kdc/check-httpkadmind.in842
-rw-r--r--third_party/heimdal/tests/kdc/check-iprop.in611
-rw-r--r--third_party/heimdal/tests/kdc/check-kadmin.in456
-rw-r--r--third_party/heimdal/tests/kdc/check-kdc-weak.in37
-rw-r--r--third_party/heimdal/tests/kdc/check-kdc.in1131
-rw-r--r--third_party/heimdal/tests/kdc/check-keys.in104
-rw-r--r--third_party/heimdal/tests/kdc/check-kinit.in149
-rw-r--r--third_party/heimdal/tests/kdc/check-kpasswdd.in194
-rw-r--r--third_party/heimdal/tests/kdc/check-pkinit.in393
-rw-r--r--third_party/heimdal/tests/kdc/check-referral.in301
-rw-r--r--third_party/heimdal/tests/kdc/check-tester.in121
-rw-r--r--third_party/heimdal/tests/kdc/check-uu.in131
-rw-r--r--third_party/heimdal/tests/kdc/donotexists.txt1
-rw-r--r--third_party/heimdal/tests/kdc/hdb-mitdbbin0 -> 16384 bytes
-rw-r--r--third_party/heimdal/tests/kdc/hdb-mitdb.kadm5bin0 -> 8192 bytes
-rw-r--r--third_party/heimdal/tests/kdc/hdb-mitdb.mkeybin0 -> 30 bytes
-rw-r--r--third_party/heimdal/tests/kdc/heimdal.acl10
-rw-r--r--third_party/heimdal/tests/kdc/iprop-acl1
-rw-r--r--third_party/heimdal/tests/kdc/k5login/foo1
-rw-r--r--third_party/heimdal/tests/kdc/k5login/mapped_user11
-rw-r--r--third_party/heimdal/tests/kdc/kdc-tester1.json31
-rw-r--r--third_party/heimdal/tests/kdc/kdc-tester2.json12
-rw-r--r--third_party/heimdal/tests/kdc/kdc-tester3.json23
-rw-r--r--third_party/heimdal/tests/kdc/kdc-tester4.json.in22
-rw-r--r--third_party/heimdal/tests/kdc/krb5-authz.conf.in26
-rw-r--r--third_party/heimdal/tests/kdc/krb5-authz2.conf.in27
-rw-r--r--third_party/heimdal/tests/kdc/krb5-bx509.conf.in182
-rw-r--r--third_party/heimdal/tests/kdc/krb5-canon.conf.in100
-rw-r--r--third_party/heimdal/tests/kdc/krb5-canon2.conf.in97
-rw-r--r--third_party/heimdal/tests/kdc/krb5-cccol.conf.in165
-rw-r--r--third_party/heimdal/tests/kdc/krb5-hdb-mitdb.conf.in60
-rw-r--r--third_party/heimdal/tests/kdc/krb5-httpkadmind.conf.in98
-rw-r--r--third_party/heimdal/tests/kdc/krb5-kcm.conf.in165
-rw-r--r--third_party/heimdal/tests/kdc/krb5-pkinit.conf.in82
-rw-r--r--third_party/heimdal/tests/kdc/krb5.conf.in175
-rw-r--r--third_party/heimdal/tests/kdc/krb5.conf.keys.in19
-rw-r--r--third_party/heimdal/tests/kdc/leaks-kill.sh27
-rw-r--r--third_party/heimdal/tests/kdc/ntlm-user-file.txt1
-rw-r--r--third_party/heimdal/tests/kdc/pki-mapping2
-rw-r--r--third_party/heimdal/tests/kdc/uuserver.txt4
-rw-r--r--third_party/heimdal/tests/kdc/wait-kdc.sh65
-rw-r--r--third_party/heimdal/tests/ldap/Makefile.am55
-rw-r--r--third_party/heimdal/tests/ldap/NTMakefile35
-rw-r--r--third_party/heimdal/tests/ldap/check-ldap.in153
-rw-r--r--third_party/heimdal/tests/ldap/init.ldif44
-rw-r--r--third_party/heimdal/tests/ldap/krb5.conf.in26
-rw-r--r--third_party/heimdal/tests/ldap/samba.schema554
-rw-r--r--third_party/heimdal/tests/ldap/slapd-init.in58
-rw-r--r--third_party/heimdal/tests/ldap/slapd-stop18
-rw-r--r--third_party/heimdal/tests/ldap/slapd.conf27
-rw-r--r--third_party/heimdal/tests/plugin/Makefile.am48
-rw-r--r--third_party/heimdal/tests/plugin/NTMakefile35
-rw-r--r--third_party/heimdal/tests/plugin/check-pac.in174
-rw-r--r--third_party/heimdal/tests/plugin/kdc_test_plugin.c209
-rw-r--r--third_party/heimdal/tests/plugin/krb5.conf.in52
120 files changed, 14996 insertions, 0 deletions
diff --git a/third_party/heimdal/tests/ChangeLog b/third_party/heimdal/tests/ChangeLog
new file mode 100644
index 0000000..ee00809
--- /dev/null
+++ b/third_party/heimdal/tests/ChangeLog
@@ -0,0 +1,793 @@
+2008-06-01 Love Hörnquist Åstrand <lha@kth.se>
+
+ * kdc/check-kadmin.in: Test globbing acl's
+
+2008-04-28 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/Makefile.am: test SDB cache.
+
+ * kdc/check-cc.in: Test SDB combinations.
+
+2008-04-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kpasswdd.in: Wait for success, use password command to
+ test it.
+
+ * kdc/check-kpasswd.in: use rkpty to test kpasswd/kpasswdd
+
+2008-03-23 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-referral.in: Fix status messages.
+
+2008-03-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Ident.
+
+2008-03-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: More verbose checks, disable check that no
+ longer works with referrals.
+
+2008-03-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-referral.in: Test TGS referrals.
+
+2008-03-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-context.in: Test gsskrb5_register_acceptor_identity.
+
+2008-02-11 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ldap/check-ldap.in: check tgs req too
+
+2008-02-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-context.in: Does not work yet error case.
+
+2008-01-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-context.in: Test unreadable/non existant keytab and
+ its error message.
+
+2008-01-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc: Test the PKCS11 provider built-in to libhx509.
+
+2007-12-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ldap/init.ldif: Add space to make valid ldiff file, from Buchan
+ Milne
+
+ * ldap/slapd-init.in: Another place where schemas are installed,
+ from Buchan Milne.
+
+2007-12-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kadmin.in: Check that admin-less principal works.
+
+2007-12-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-ntlm.in: test kdigest digest-probe command.
+
+2007-12-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-basic.in: Test GSS_C_NO_NAME too.
+
+2007-10-24 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Try multiple enctypes.
+
+2007-08-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * java/Makefile.am: EXTRA_DIST += jaas.conf
+
+2007-08-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * java/Makefile.am: Add java source code.
+
+2007-08-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-iprop.in: Don't run this test in AFS since AFS is
+ missing unix sockets.
+
+ * kdc/wait-kdc.sh: Catch bind ../../tests/kdc/signal: Operation
+ not permitted
+
+2007-08-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-iprop.in: use wait-kdc.sh for all diffrent places we
+ start ipropd-{master,slave}.
+
+ * all-tests: empty messages.log
+
+ * kdc/check-iprop.in: Use wait-kdc.sh to wait for
+ ipropd-{master,slave}.
+
+ * kdc/wait-kdc.sh: look futher back in the logfile.
+
+ * kdc/wait-kdc.sh: Make wait-kdc.sh able to wait on other things.
+
+ * kdc/check-iprop.in: Checking master going backward, create
+ iprop-stats.
+
+2007-08-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * java/have-java.sh: GNU GCC Java doesn't support Kerberos
+
+2007-08-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-iprop.in: wait longer for iprop, dump messages.log on
+ failure.
+
+ * kdc/Makefile.am: Clean after iprop tests.
+
+ * kdc/check-iprop.in: more iprop tests.
+
+2007-07-31 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/Makefile.am: Add check-iprop and related files.
+
+ * kdc/krb5.conf.in: Add stuff for iprop.
+
+ * kdc/check-iprop.in: Test for iprop.
+
+ * kdc/iprop-acl: ACL file for iprop.
+
+2007-07-28 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/donotexists.txt: missing file.
+
+2007-07-26 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/Makefile.am: EXTRA_DIST += donotexists.txt
+
+2007-07-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Test renewing.
+
+2007-07-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/Makefile.am: Test for simple salt types.
+
+ * kdc/krb5.conf.keys.in: Configuration file for testing keys.
+
+ * kdc/check-keys.in: Test some simple salt types.
+
+2007-07-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * java/Makefile.am: EXTRA_DIST += have_java.sh
+
+ * java/check-kinit.in: Make failing to compile a java program a
+ no-fatal error.
+
+ * java/check-kinit.in: Disable test if we use socket wrapper.
+
+2007-07-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kadmin.in: Give more hints of what went wrong.
+
+2007-07-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/Makefile.am: add check-kadmin.in
+
+2007-07-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ldap/slapd.conf: add samba.schema.
+
+ * ldap/slapd-init.in: Add samba schema.
+
+ * ldap/init.ldif: Samba entry to do testing with.
+
+2007-07-11 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * java/check-kinit.in: Only print when there is an error.
+
+ * java/krb5.conf.in: Move the AES enctypes first.
+
+2007-07-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kadmin.in: Send kill outout to /dev/null.
+
+ * kdc/krb5.conf.in: Add bits needed for kadmind server test.
+
+ * kdc/Makefile.am: Add check-kadmin.
+
+ * kdc/check-kadmin.in: Simple test for server based kadmin.
+
+ * kdc/heimdal.acl: ACL file for check-admin test.
+
+2007-07-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: Add java.
+
+ * java: simple java kinit test
+
+2007-06-26 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ldap/check-ldap.in: Add one more principal and list the
+ database.
+
+ * kdc/check-pkinit.in: Fix hxtool issue-certificate --req.
+
+ * kdc/check-referral.in: Spelling.
+
+2007-06-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-context.in: disable dns canon on test, break on some
+ buildfarm hosts.
+
+2007-06-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * can/test_can.in: readline seems strange, try diffrent way to
+ setup the database.
+
+2007-06-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * can/test_can.in: spoon feed kadmin diffrently
+
+2007-06-11 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Also test rename user to anther realm.
+
+ * kdc/check-kdc.in: Test renaming a user.
+
+ * can/test_can.in: Tell use what the messages.log told us.
+
+ * kdc/check-referral.in: Add some more as-req canon tests, add
+ disable tgs-req tests.
+
+2007-06-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * can/check-can.in: Check is there is a working db backend here.
+
+2007-06-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * can/Makefile.am: Clean up more cruft.
+
+2007-06-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * can/Makefile.am: More files we want in the dist.
+
+ * can/test_can.in: Simplify error reporting.
+
+ * can/test_can.in: Catch error from kadmin.
+
+ * can/mit-pkinit-20070607.*: mit pkinit-9 request
+
+ * can/check-can.in: Add mit-pkinit test.
+
+ * can/Makefile.am: Create specific configurtion files for some
+ tests.
+
+ * can/test_can.in: Pick up the right generated
+ krb5.conf (spelling).
+
+ * can: Add Apple Tiger 10.4/MIT Kerberos 1.4
+
+ * can/test_can.in: Don't need to start a kdc for this test.
+
+ * can: pre-canned requests from older versions and other implementations
+
+ * Makefile.am: SUBDIRS += can
+
+2007-06-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-uu.in: Use stdout from uu_server.
+
+2007-05-31 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-pkinit.in: Try pkinit in w2k mode, also add tests for
+ MS SAN.
+
+ * kdc/Makefile.am: generate a krb5-pkinit-win.conf
+
+ * kdc/krb5-pkinit.conf.in: W2K tests.
+
+2007-05-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/Makefile.am: remove more files
+
+2007-05-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-pkinit.in: try principal subject in DB
+
+2007-05-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-basic.in: test using test_kcred
+
+ * gss/check-ntlm.in: One more test.
+
+ * ldap/check-ldap.in: check in /usr/lib/openldap too for slapd and
+ slapadd
+
+2007-05-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * db/add-modify-delete.in: Remove comment.
+
+ * db/add-modify-delete.in: try replay
+
+ * db/Makefile.am: clean more files.
+
+ * db/add-modify-delete.in: try iprop-log commands.
+
+2007-04-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * db/krb5.conf.in: Add longer example.
+
+2007-04-23 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * db: basic tests for dbinfo
+
+2007-04-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/Makefile.am: Add check-ntlm.
+
+ * gss/check-ntlm.in: test ntlm client credentials code.
+
+2007-04-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * db/loaddump-db.in: make kstash quiet
+
+2007-04-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-basic.in: more gss_acquire_cred tests
+
+2007-04-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/Makefile.am: add check-basic
+
+ * gss/check-basic.in: basic tests that might require a KDC.
+
+2007-04-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/Makefile.am: CLEANFILES += sdigest-init
+
+2007-04-11 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * ldap/slapd-init.in: Add Id tag
+
+2007-02-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: test new kadmin add_enctype functionallity
+
+2007-02-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: add ldap
+
+ * kdc/check-referral.in: add check-referral
+
+ * kdc/Makefile.am: add check-referral
+
+2007-02-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * tests/ldap: simple ldap test, inspried by samba ldb ldap test
+
+2007-02-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-digest.in: Test ms-chap-v2 (client response, server
+ response, session key)
+
+2007-02-02 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/krb5.conf.in: allow ms-chap-v2
+
+2007-02-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-digest.in: Negative check too.
+
+2007-01-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-uu.in: save log, wait longer
+
+2007-01-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-pkinit.in: tell me about certifiate that we have
+ generated
+
+2007-01-11 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * no random, no RSA/DH tests
+
+ * plugin/Makefile.am: remove files created by tests
+
+ * gss/Makefile.am: remove files created by tests
+
+ * gss/Makefile.am: add ntlm-user-file.txt
+
+2007-01-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/ap-req.c: --verify-pac no means verify existance of PAC in
+ ticket, the signature checking is done by the kerberos library.
+
+ * kdc/check-digest.in: display messages.log and help that that
+ tells us what went wrong.
+
+ * plugin/windc.c: Update to validate function signature change.
+
+ * Makefile.am: Only traverse into plugin if there is shared
+ library support.
+
+2007-01-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-pkinit.in: Prefix key with FILE:
+
+2007-01-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * plugin/Makefile.am: EXTRA_DIST += krb5.conf.in
+
+ * plugin/check-pac.in: test explicit requested pac and explicit
+ negative requested pac.
+
+ * kdc/ap-req.c: Make it possible to turn off PAC check, its
+ default on.
+
+ * plugin/windc.c: Add client_access.
+
+ * plugin/check-pac.in: Verify PAC on server end too.
+
+ * kdc/ap-req.c: Add verification of PAC.
+
+ * kdc/Makefile.am: Add test for pkinit with locally generated
+ certs.
+
+ * kdc/check-pkinit.in: Generate a ca, kdc cert and client cert and
+ try to use them
+
+ * kdc/pki-mapping: add other foo@TEST
+
+ * kdc/krb5-pkinit.conf.in: pkinit specific krb5.conf
+
+2007-01-03 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * plugin/check-pac.in: test tgs-req
+
+ * plugin/windc.c: log that the function is called.
+
+ * kdc/check-digest.in: Test security layer in ntlm.
+
+ * plugin: test WinDC PAC functionallity
+
+ * Makefile.am: Include plugin in tests
+
+2006-12-28 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/ntlm-user-file.txt: Correct DOMAIN name
+
+2006-12-26 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/krb5.conf.in: Add digests acls (all)
+
+2006-12-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-spnego.in: test wrapunwrap
+
+ * gss/check-spnego.in: Test get and verify MIC.
+
+ * gss/check-context.in: don't need to set GSSAPI_SPNEGO_NAME any
+ longer
+
+2006-12-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-context.in: Define GSSAPI_SPNEGO_NAME and re-add
+ spnego
+
+ * gss/check-context.in: add trap, remove allow-digest, pretty
+ print.
+
+ * gss/check-gssmask.in: catch EXIT traps
+
+ * gss/check-spnego.in: test more combination of spnego contexts
+
+ * gss/Makefile.am: add check-spnego
+
+ * gss/check-spnego.in: check spnego combinations.
+
+2006-12-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-digest.in: test more combinations of names
+
+2006-12-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/ntlm-user-file.txt: ntlm username and password file
+
+ * kdc/check-digest.in: Check that ntlm works.
+
+2006-12-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-digest.in: prefix digest commands with digest-
+
+2006-11-29 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Don't (afs) unlog using kdestroy
+
+2006-11-25 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/Makefile.am: Add LIB_roken and (implictly by that libvers
+ for print_version) to LDADD
+
+2006-11-23 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: check that the getarg -- option works for
+ delete and add.
+
+ * kdc/check-kdc.in: Test proxy cert.
+
+2006-11-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/krb5.conf.in: revert the enable-pkinit change, and make it
+ consistant with all other other enable- options
+
+2006-11-15 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-context.in: Add dce-style context building test.
+
+ * gss/check-context.in: test more combination of context building
+
+2006-11-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Use TEST{,2}.H5L.SE for testing
+
+2006-11-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/Makefile.am: Use EGREP.
+
+ * kdc/check-kdc.in: Use EGREP.
+
+2006-10-23 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: run eval on the testfailed variable so we run
+ all commands
+
+2006-10-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * db/Makefile.am: make have-db being built in the "make all"
+ target.
+
+ * kdc/check-kdc.in: tell more what the kdc though about the
+ failure.
+
+2006-10-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * db/add-modify-delete.in: Use EGREP.
+
+ * db/Makefile.am: add EGREP to do_subst
+
+2006-10-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/Makefile.am: Clean temporary files
+
+ * db/Makefile.am: clean have-db
+
+ * kdc/Makefile.am: Add pki-mapping to dist file.
+
+ * kdc/Makefile.am: more files
+
+ * db/Makefile.am: more files
+
+2006-10-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-context.in: give path to have-db
+
+ * gss/check-gssmask.in: give path to have-db
+
+ * kdc/check-kdc.in: give path to have-db
+
+ * kdc/check-digest.in: give path to have-db
+
+ * gss/check-gssmask.in: If there is no useful db support compile
+ in, disable test
+
+ * gss/check-context.in: Add commeted out digest check.
+
+ * kdc/check-digest.in: If there is no useful db support compile
+ in, disable test
+
+ * kdc/check-kdc.in: If there is no useful db support compile in,
+ disable test
+
+ * db/loaddump-db.in: If there is no useful db support compile in,
+ disable test
+
+ * db/have-db.in: Check if the kdc have any useful builtin
+ database.
+
+ * kdc/check-kdc.in: Fix awk statement, put RE on the right side.
+
+2006-10-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-gssmask.in: remove dup exit
+
+ * gss/check-context.in: More name tests.
+
+ * gss/check-context.in: test with and without dns-canon
+
+2006-10-14 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Be more explit about what test failed.
+
+2006-10-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-context.in: et KRB5CCNAME in global enviorment
+
+2006-10-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/Makefile.am: Check if the gss context tester test_context
+ works ok.
+
+ * gss/check-context.in: Check if the gss context tester
+ test_context works ok.
+
+2006-10-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-gssmask.in: use wait-kdc.sh script
+
+ * kdc/check-kdc.in: use wait-kdc.sh script
+
+ * kdc/check-digest.in: use wait-kdc.sh script
+
+ * Heimdal uses TESTS_ENVIRONMENT before every binary being tested
+ directly from the Makefile. This now uses the same for the
+ scripts, so we can run them under valgrind. From Andrew Bartlet
+
+2006-10-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/Makefile.am: splits script tests and binary tests
+
+ * db/Makefile.am: Add tests script depenencies
+
+ * kdc/Makefile.am: Split script tests and binary tests
+
+2006-10-04 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Test pkinit encKey case.
+
+2006-09-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-gssmask.in: Catch failures from gssmaestro.
+
+2006-09-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-gssmask.in: Add a third client
+
+2006-09-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-gssmask.in: test for gssmask + gssmaestro.
+
+ * gss/krb5.conf.in: Add krb5.conf for krb5.conf
+
+2006-09-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * gss/check-gss.in: Add (c)
+
+ * kdc/check-kdc.in: Test constrained delegation impersonation.
+
+2006-09-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Change the password on krbtgt a couple of
+ times to have a non boring kvno.
+
+2006-08-24 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-digest.in: Use the server as the server and set
+ diffrent password for the user and service.
+
+ * kdc/check-digest.in: Set allow digest flag on the server.
+
+ * kdc/Makefile.am: Build and run check-digest test.
+
+ * kdc/check-digest.in: Remove channel bindings from CHAP tests,
+ there is no such thing for CHAP.
+
+ * kdc/check-kdc.in: Test aes only krbtgt and des3 only service.
+
+2006-08-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Remove empty lines for picky awks
+
+2006-07-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Check for cross realm case where remove user
+ doesn't exists in the database, this is ok assuming the cross
+ realm isn't local. In the general case this isn't true.
+
+2006-06-22 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: run kadmin check
+
+2006-06-07 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: test that delegated cred works too
+
+ * kdc/check-kdc.in: Test delegation
+
+2006-06-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Add impersonation tests.
+
+2006-06-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Less verbose, spelling.
+
+ * kdc/check-kdc.in: test cross realm and deleted user
+
+2006-05-12 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Check password protected pk-init keyfile.
+
+2006-04-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Don't try pkinit if there is no rsa
+
+2006-04-29 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/pki-mapping: change pki-mapping
+
+ * kdc/Makefile.am: clean the server.keytab
+
+ * kdc/check-kdc.in: Add test for pk-init
+
+ * kdc/krb5.conf.in: Add pkinit glue
+
+2006-04-28 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/pki-mapping: Add pk-init mapping file
+
+2006-04-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * kdc/check-kdc.in: Sprinkle more ap-req now that the credential
+ is removed from the cache using kdestroy --credential=
+
+ * kdc/ap-req.c: check that AP_OPTS_MUTUAL_REQUIRED matches, check
+ seqnumber
+
+ * kdc/Makefile.am: Build as-req.
+
+ * kdc/check-kdc.in: Sprinkel some as-req
+
+ * kdc/ap-req.c: simple test program checking that as ap-req/as-rep
+ exchange works
+
+2006-04-25 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * {,kdc/,db/}.cvsignore: ignore Makefile.in
+
+ * kdc/check-kdc.in: Try to detect another KDC running.
+
+ * kdc/check-kdc.in: more tests regarding doing AS-REQ and TGS-REQ
+
+ * kdc/krb5.conf.in: krb5.conf template
+
+ * kdc/check-kdc.in: check that the keytab have the right kvno
+
+ * db/add-modify-delete.in: create a server too
+
+ * kdc/check-kdc.in: check kdc too
+
+ * db/Makefile.am: Add add-modify-delete
+
+ * db/add-modify-delete.in: basic kadmin tests
+
+ * Makefile.am: SUBDIRS += kdc
+
+ * kdc/check-kdc.in: Test framework for getting and checking
+ tickets, start kdc on localhost:8888.
+
+ * kdc/Makefile.am: Test framework for getting and checking
+ tickets.
+
+ * db/krb5.conf.in: log all message to local file
+
+ * db/Makefile.am: clean messages file
+
+2006-01-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * db/krb5.conf.in: Set [libdefaults] default_realm = EXAMPLE.ORG.
+
+2005-11-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * db/loaddump-db.in: Specifify explicitly that the database is in
+ the current directory.
+
+2005-08-11 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test loading and dumping of the database
diff --git a/third_party/heimdal/tests/Makefile.am b/third_party/heimdal/tests/Makefile.am
new file mode 100644
index 0000000..aad29fa
--- /dev/null
+++ b/third_party/heimdal/tests/Makefile.am
@@ -0,0 +1,13 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+SUBDIRS = bin db gss ldap can java kdc
+
+if ENABLE_SHARED
+if HAVE_DLOPEN
+SUBDIRS += plugin
+endif
+endif
+
+EXTRA_DIST = NTMakefile
diff --git a/third_party/heimdal/tests/NTMakefile b/third_party/heimdal/tests/NTMakefile
new file mode 100644
index 0000000..8a1698e
--- /dev/null
+++ b/third_party/heimdal/tests/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=tests
+
+!include ../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/tests/bin/Makefile.am b/third_party/heimdal/tests/bin/Makefile.am
new file mode 100644
index 0000000..98bb342
--- /dev/null
+++ b/third_party/heimdal/tests/bin/Makefile.am
@@ -0,0 +1,30 @@
+include $(top_srcdir)/Makefile.am.common
+
+noinst_SCRIPTS = setup-env
+
+noinst_PROGRAMS = intr
+
+intr_SOURCES = intr.c
+
+CHECK_LOCAL = no-check-local
+
+intr_LDADD = $(LIB_roken)
+
+do_subst = \
+ top_srcdir="$$(cd ${top_srcdir} && pwd)" ; \
+ top_builddir="$$(cd ${top_builddir} && pwd)" ; \
+ sed $(do_dlopen) \
+ -e "s,[@]EGREP[@],$(EGREP),g" \
+ -e "s,[@]top_srcdir[@],$${top_srcdir},g" \
+ -e "s,[@]top_builddir[@],$${top_builddir},g" \
+ -e "s,[@]NO_AFS[@],$(NO_AFS),g"
+
+setup-env: setup-env.in Makefile
+ $(do_subst) < $(srcdir)/setup-env.in > setup-env.tmp
+ chmod +x setup-env.tmp
+ mv setup-env.tmp setup-env
+
+EXTRA_DIST = setup-env.in
+
+CLEANFILES = setup-env setup-env.tmp
+
diff --git a/third_party/heimdal/tests/bin/intr.c b/third_party/heimdal/tests/bin/intr.c
new file mode 100644
index 0000000..867c5c2
--- /dev/null
+++ b/third_party/heimdal/tests/bin/intr.c
@@ -0,0 +1,56 @@
+#include <config.h>
+
+#include <getarg.h>
+#include <roken.h>
+#include <time.h>
+
+static int help_flag;
+static int timeout = 3;
+
+static struct getargs args[] = {
+ { "help", 'h', arg_flag, &help_flag, NULL, NULL },
+ { "timeout", 't', arg_integer, &timeout, NULL, NULL }
+};
+
+static int nargs = sizeof(args) / sizeof(args[0]);
+
+static time_t
+handle_timeout(void *data)
+{
+ static int killed;
+
+ if (!killed++)
+ return -1; /* kill it */
+ return -2; /* stop waiting for it */
+}
+
+static void
+usage(int status)
+{
+ arg_printusage(args, nargs, NULL, "command");
+ exit(status);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int optidx = 0;
+
+ setprogname(argv[0]);
+
+ if (getarg(args, nargs, argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage(0);
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc == 0)
+ usage(1);
+
+ return simple_execvp_timed(argv[0], argv, handle_timeout, NULL,
+ timeout);
+}
diff --git a/third_party/heimdal/tests/bin/setup-env.in b/third_party/heimdal/tests/bin/setup-env.in
new file mode 100644
index 0000000..8efa0e9
--- /dev/null
+++ b/third_party/heimdal/tests/bin/setup-env.in
@@ -0,0 +1,89 @@
+#!/bin/sh
+
+HEIM_PIDFILE_DIR="${objdir}/"
+export HEIM_PIDFILE_DIR
+
+unset KRB5_CONFIG
+unset KRB5CCNAME
+
+unset GSS_MECH_CONFIG
+unset GSSAPI_SPNEGO_NAME
+
+top_builddir="@top_builddir@"
+top_srcdir="@top_srcdir@"
+EGREP="@EGREP@"
+NO_AFS="@NO_AFS@"
+MITKRB5="@MITKRB5@"
+
+# Meant to be sourced (source or .) by the tester application, offers
+# most commands in heimdal as variables
+
+# regular apps
+bx509d="${TESTS_ENVIRONMENT} ${top_builddir}/kdc/bx509d"
+httpkadmind="${TESTS_ENVIRONMENT} ${top_builddir}/kdc/httpkadmind"
+hxtool="${TESTS_ENVIRONMENT} ${top_builddir}/lib/hx509/hxtool"
+iprop_log="${TESTS_ENVIRONMENT} ${top_builddir}/lib/kadm5/iprop-log"
+ipropd_master="${TESTS_ENVIRONMENT} ${top_builddir}/lib/kadm5/ipropd-master"
+ipropd_slave="${TESTS_ENVIRONMENT} ${top_builddir}/lib/kadm5/ipropd-slave"
+kadmin="${TESTS_ENVIRONMENT} ${top_builddir}/kadmin/kadmin"
+kadmind="${TESTS_ENVIRONMENT} ${top_builddir}/kadmin/kadmind"
+kdc="${TESTS_ENVIRONMENT} ${top_builddir}/kdc/kdc"
+kdc_tester="${TESTS_ENVIRONMENT} ${top_builddir}/kdc/kdc-tester"
+kcm="${TESTS_ENVIRONMENT} ${top_builddir}/kcm/kcm"
+test_csr_authorizer="${TESTS_ENVIRONMENT} ${top_builddir}/kdc/test_csr_authorizer"
+test_kdc_ca="${TESTS_ENVIRONMENT} ${top_builddir}/kdc/test_kdc_ca"
+test_token_validator="${TESTS_ENVIRONMENT} ${top_builddir}/kdc/test_token_validator"
+kdestroy="${TESTS_ENVIRONMENT} ${top_builddir}/kuser/kdestroy"
+kdigest="${TESTS_ENVIRONMENT} ${top_builddir}/kuser/kdigest"
+kgetcred="${TESTS_ENVIRONMENT} ${top_builddir}/kuser/kgetcred"
+kimpersonate="${TESTS_ENVIRONMENT} ${top_builddir}/kuser/kimpersonate"
+kinit="${TESTS_ENVIRONMENT} ${top_builddir}/kuser/kinit"
+klist="${TESTS_ENVIRONMENT} ${top_builddir}/kuser/heimtools klist"
+kpasswd="${TESTS_ENVIRONMENT} ${top_builddir}/kpasswd/kpasswd"
+kpasswdd="${TESTS_ENVIRONMENT} ${top_builddir}/kpasswd/kpasswdd"
+kswitch="${TESTS_ENVIRONMENT} ${top_builddir}/kuser/heimtools kswitch"
+kx509="${TESTS_ENVIRONMENT} ${top_builddir}/kuser/heimtools kx509"
+ktutil="${TESTS_ENVIRONMENT} ${top_builddir}/admin/ktutil"
+gsstool="${TESTS_ENVIRONMENT} ${top_builddir}/lib/gssapi/gsstool"
+gsstoken="${TESTS_ENVIRONMENT} ${top_builddir}/lib/gssapi/gss-token"
+
+# regression test tools
+test_ap_req="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_ap-req"
+test_canon="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_canon"
+test_gic="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_gic"
+test_renew="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_renew"
+test_ntlm="${TESTS_ENVIRONMENT} ${top_builddir}/lib/gssapi/test_ntlm"
+test_context="${TESTS_ENVIRONMENT} ${top_builddir}/lib/gssapi/test_context"
+rkbase64="${TESTS_ENVIRONMENT} ${top_builddir}/lib/roken/rkbase64"
+rkpty="${TESTS_ENVIRONMENT} ${top_builddir}/lib/roken/rkpty"
+rkvis="${TESTS_ENVIRONMENT} ${top_builddir}/lib/roken/rkvis"
+test_set_kvno0="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_set_kvno0"
+test_alname="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_alname"
+test_kuserok="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_kuserok"
+test_mkforwardable="${TESTS_ENVIRONMENT} ${top_builddir}/lib/krb5/test_mkforwardable"
+
+# misc apps
+have_db="${top_builddir}/tests/db/have-db"
+leaks_kill="${top_srcdir}/tests/kdc/leaks-kill.sh"
+wait_kdc="${top_srcdir}/tests/kdc/wait-kdc.sh"
+getpid () {
+ if [ -f "$HEIM_PIDFILE_DIR/lt-${1}.pid" ]; then
+ cat "$HEIM_PIDFILE_DIR/lt-${1}.pid"
+ else
+ cat "$HEIM_PIDFILE_DIR/${1}.pid"
+ fi
+}
+
+if [ ! "${NO_AFS}" ] ; then
+ afs_no_unlog="--no-unlog"
+ afs_no_afslog="--no-afslog"
+else
+ afs_no_unlog=""
+ afs_no_afslog=""
+fi
+
+# data
+hx509_data="${top_srcdir}/lib/hx509/data"
+
+# malloc debug
+HEIM_MALLOC_DEBUG="MallocStackLoggingNoCompact=1 MallocErrorAbort=1 MallocLogFile=/tmp/heim-malloc-log"
diff --git a/third_party/heimdal/tests/can/Makefile.am b/third_party/heimdal/tests/can/Makefile.am
new file mode 100644
index 0000000..8caf293
--- /dev/null
+++ b/third_party/heimdal/tests/can/Makefile.am
@@ -0,0 +1,58 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+noinst_DATA = krb5.conf mit-pkinit-20070607.cf
+
+check_SCRIPTS = $(SCRIPT_TESTS) test_can
+
+SCRIPT_TESTS = check-can
+TESTS = $(SCRIPT_TESTS)
+
+port = 49188
+
+do_subst = sed -e 's,[@]srcdir[@],$(srcdir),g' \
+ -e 's,[@]port[@],$(port),g' \
+ -e 's,[@]objdir[@],$(top_builddir)/tests/can,g' \
+ -e 's,[@]EGREP[@],$(EGREP),g' \
+ -e 's,[@]env_setup[@],$(top_builddir)/tests/bin/setup-env,g'
+
+test_can: test_can.in Makefile
+ $(do_subst) < $(srcdir)/test_can.in > test_can.tmp
+ chmod +x test_can.tmp
+ mv test_can.tmp test_can
+
+check-can: check-can.in Makefile
+ $(do_subst) < $(srcdir)/check-can.in > check-can.tmp
+ chmod +x check-can.tmp
+ mv check-can.tmp check-can
+
+krb5.conf: krb5.conf.in Makefile
+ $(do_subst) < $(srcdir)/krb5.conf.in > krb5.conf.tmp
+ mv krb5.conf.tmp krb5.conf
+
+SUFFIXES += .xf .cf
+
+.xf.cf:
+ $(do_subst) < $< > $@.tmp
+ mv $@.tmp $@
+
+CLEANFILES= $(TESTS) *.tmp *.cf \
+ current-db* \
+ krb5.conf \
+ messages.log \
+ test_can
+
+EXTRA_DIST = \
+ NTMakefile \
+ apple-10.4.kadm \
+ apple-10.4.req \
+ check-can.in \
+ heim-0.8.kadm \
+ heim-0.8.req \
+ krb5.conf.in \
+ mit-pkinit-20070607.ca.crt \
+ mit-pkinit-20070607.kadm \
+ mit-pkinit-20070607.req \
+ mit-pkinit-20070607.xf \
+ test_can.in
diff --git a/third_party/heimdal/tests/can/NTMakefile b/third_party/heimdal/tests/can/NTMakefile
new file mode 100644
index 0000000..09efe5e
--- /dev/null
+++ b/third_party/heimdal/tests/can/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=tests\can
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/tests/can/apple-10.4.kadm b/third_party/heimdal/tests/can/apple-10.4.kadm
new file mode 100644
index 0000000..a10904b
--- /dev/null
+++ b/third_party/heimdal/tests/can/apple-10.4.kadm
@@ -0,0 +1,4 @@
+init --realm-max-ticket-life=1day --realm-max-renewable-life=1month TEST.H5L.SE
+cpw -p kaka krbtgt/TEST.H5L.SE@TEST.H5L.SE
+add -p foo --use-defaults foo@TEST.H5L.SE
+add -p foo --use-defaults bar@TEST.H5L.SE
diff --git a/third_party/heimdal/tests/can/apple-10.4.req b/third_party/heimdal/tests/can/apple-10.4.req
new file mode 100644
index 0000000..7acc80b
--- /dev/null
+++ b/third_party/heimdal/tests/can/apple-10.4.req
Binary files differ
diff --git a/third_party/heimdal/tests/can/check-can.in b/third_party/heimdal/tests/can/check-can.in
new file mode 100644
index 0000000..50d01b8
--- /dev/null
+++ b/third_party/heimdal/tests/can/check-can.in
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+env_setup="@env_setup@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+./test_can TEST.H5L.SE heim-0.8 || exit 1
+./test_can TEST.H5L.SE apple-10.4 || exit 1
+
+rsa=yes
+pkinit=no
+if ${hxtool} info | grep 'rsa: hx509 null RSA' > /dev/null ; then
+ rsa=no
+fi
+if ${hxtool} info | grep 'rand: not available' > /dev/null ; then
+ rsa=no
+fi
+if ${kinit} --help 2>&1 | grep "CA certificates" > /dev/null; then
+ pkinit=yes
+fi
+
+if test "$pkinit" = yes -a "$rsa" = yes ; then
+ ./test_can HEIMDAL.CITI.UMICH.EDU mit-pkinit-20070607 || exit 1
+fi
+
+exit 0
diff --git a/third_party/heimdal/tests/can/heim-0.8.kadm b/third_party/heimdal/tests/can/heim-0.8.kadm
new file mode 100644
index 0000000..a10904b
--- /dev/null
+++ b/third_party/heimdal/tests/can/heim-0.8.kadm
@@ -0,0 +1,4 @@
+init --realm-max-ticket-life=1day --realm-max-renewable-life=1month TEST.H5L.SE
+cpw -p kaka krbtgt/TEST.H5L.SE@TEST.H5L.SE
+add -p foo --use-defaults foo@TEST.H5L.SE
+add -p foo --use-defaults bar@TEST.H5L.SE
diff --git a/third_party/heimdal/tests/can/heim-0.8.req b/third_party/heimdal/tests/can/heim-0.8.req
new file mode 100644
index 0000000..43b3a68
--- /dev/null
+++ b/third_party/heimdal/tests/can/heim-0.8.req
Binary files differ
diff --git a/third_party/heimdal/tests/can/krb5.conf.in b/third_party/heimdal/tests/can/krb5.conf.in
new file mode 100644
index 0000000..275f956
--- /dev/null
+++ b/third_party/heimdal/tests/can/krb5.conf.in
@@ -0,0 +1,29 @@
+# $Id$
+
+[libdefaults]
+ default_realm = TEST.H5L.SE
+ no-addresses = TRUE
+
+[appdefaults]
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+
+[kdc]
+ database = {
+ dbname = @objdir@/current-db
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ log_file = @objdir@/current.log
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ kdc-replay = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
diff --git a/third_party/heimdal/tests/can/mit-pkinit-20070607.ca.crt b/third_party/heimdal/tests/can/mit-pkinit-20070607.ca.crt
new file mode 100644
index 0000000..5874788
--- /dev/null
+++ b/third_party/heimdal/tests/can/mit-pkinit-20070607.ca.crt
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID4zCCAsugAwIBAgICNOswDQYJKoZIhvcNAQEFBQAwczELMAkGA1UEBhMCVVMx
+ETAPBgNVBAgTCE1pY2hpZ2FuMRIwEAYDVQQHEwlBbm4gQXJib3IxHzAdBgNVBAoT
+FlVuaXZlcnNpdHkgb2YgTWljaGlnYW4xHDAaBgNVBAMTE0NJVEkgUHJvZHVjdGlv
+biBLQ0EwHhcNMDYxMDEzMTYxNTIyWhcNMTYxMDEyMTYxNTIyWjBzMQswCQYDVQQG
+EwJVUzERMA8GA1UECBMITWljaGlnYW4xEjAQBgNVBAcTCUFubiBBcmJvcjEfMB0G
+A1UEChMWVW5pdmVyc2l0eSBvZiBNaWNoaWdhbjEcMBoGA1UEAxMTQ0lUSSBQcm9k
+dWN0aW9uIEtDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM85fWVD
+rneI9CM9NvpSw1PO571/8RhBiY1p0hMFi9ppD4Xaztswz0nrCEpuAhtXUxF+H6CS
+aAXFLiY/SQhj3JGpVw3yPE2CeGtmcMjDDxOW5Raw0XwbK/BdgYFg/AU5FH7RtOV7
+pnhBlk5oJt0VJyJs+NNw4+V2IqODRvX88AR6dDAd8TpbZJEdgoGU+LHaC6cha6WU
+p6nmjVx0TLUvIa16NFZGs44bNIIt7cI6zil/dM76881APTbYcB8hGqQJiphqX6ff
+HI3uiHclK2rOZufRqhn0NJNWDCrK55PXQX67UmKBLqAsoFSJDPD+cBIUXtVeFLGs
+uJYK8F9FaN3r9XsCAwEAAaOBgDB+MA8GA1UdEwQIMAYBAf8CAQAwEQYJYIZIAYb4
+QgEBBAQDAgAHMAsGA1UdDwQEAwIBhjAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBH
+ZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFGXMLAou01gvxxcJc+Tvat/T
+QHwwMA0GCSqGSIb3DQEBBQUAA4IBAQC99gg/E230FPGmDaP4YecmtSSGOnD+jJ+A
+sPcJKaeS3dOGDTngKCzzQZ4nl7LYRSj5DWZTTrlrKfbc6GiUE0n/K/+GBvL/kjOV
+qZsyGNfepscVe6mPz43NoNztf/1j+0QQcioHHHtAq/YFPBp1VdYsOsB+IE+g8RVi
+EDjsvmR/++s9zX5fGuVvN7RNwLFrxfqcPFZCUG8pkIHbBPRhRV/aOKHGMcThNrtC
+9cZ8xaDwhP0fdSUVESGFj+MMQCAp8YZvypJuHTYX7Ng4OMdCOPPg4Kk1ycOGAcYe
+o/m7ICx1md6Va9zEfwqmrXVxGaT0I23lI9H9sv+ugvZ3v5iedhO/
+-----END CERTIFICATE-----
diff --git a/third_party/heimdal/tests/can/mit-pkinit-20070607.kadm b/third_party/heimdal/tests/can/mit-pkinit-20070607.kadm
new file mode 100644
index 0000000..6a23c67
--- /dev/null
+++ b/third_party/heimdal/tests/can/mit-pkinit-20070607.kadm
@@ -0,0 +1,3 @@
+init --realm-max-ticket-life=1day --realm-max-renewable-life=1month HEIMDAL.CITI.UMICH.EDU
+cpw -p kaka krbtgt/HEIMDAL.CITI.UMICH.EDU@HEIMDAL.CITI.UMICH.EDU
+add -p foo --use-defaults aglo@HEIMDAL.CITI.UMICH.EDU
diff --git a/third_party/heimdal/tests/can/mit-pkinit-20070607.req b/third_party/heimdal/tests/can/mit-pkinit-20070607.req
new file mode 100644
index 0000000..652bbcf
--- /dev/null
+++ b/third_party/heimdal/tests/can/mit-pkinit-20070607.req
Binary files differ
diff --git a/third_party/heimdal/tests/can/mit-pkinit-20070607.xf b/third_party/heimdal/tests/can/mit-pkinit-20070607.xf
new file mode 100644
index 0000000..1c74786
--- /dev/null
+++ b/third_party/heimdal/tests/can/mit-pkinit-20070607.xf
@@ -0,0 +1,31 @@
+# $Id$
+
+[libdefaults]
+ default_realm = HEIMDAL.CITI.UMICH.EDU
+ no-addresses = TRUE
+
+[appdefaults]
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+
+[kdc]
+ enable-pkinit = yes
+ pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt,@srcdir@/mit-pkinit-20070607.ca.crt
+
+ database = {
+ dbname = @objdir@/current-db
+ realm = HEIMDAL.CITI.UMICH.EDU
+ mkey_file = @objdir@/mkey.file
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
diff --git a/third_party/heimdal/tests/can/test_can.in b/third_party/heimdal/tests/can/test_can.in
new file mode 100644
index 0000000..3cda220
--- /dev/null
+++ b/third_party/heimdal/tests/can/test_can.in
@@ -0,0 +1,79 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+srcdir="@srcdir@"
+objdir="@objdir@"
+EGREP="@EGREP@"
+
+R=$1
+tst=$2
+
+if [ ! -f ${srcdir}/${tst}.req ] ; then
+ echo "${tst}.req missing"
+fi
+if [ ! -f ${srcdir}/${tst}.kadm ] ; then
+ echo "${tst}.kadm missing"
+fi
+
+port=@port@
+
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r $R"
+replay="${TESTS_ENVIRONMENT} ../../kdc/kdc-replay"
+
+if [ -f ${objdir}/${tst}.cf ]; then
+ KRB5_CONFIG="${objdir}/${tst}.cf"
+else
+ KRB5_CONFIG="${objdir}/krb5.conf"
+fi
+export KRB5_CONFIG
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+echo "Load database for ${tst}"
+while read x ; do
+ ${kadmin} $x || exit 1
+done < ${srcdir}/${tst}.kadm || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+> messages.log
+${replay} ${srcdir}/${tst}.req || { cat messages.log ; exit 1; }
+
+exit 0
diff --git a/third_party/heimdal/tests/db/Makefile.am b/third_party/heimdal/tests/db/Makefile.am
new file mode 100644
index 0000000..9597a0b
--- /dev/null
+++ b/third_party/heimdal/tests/db/Makefile.am
@@ -0,0 +1,103 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+noinst_DATA = krb5.conf krb5.conf-sqlite krb5.conf-db3 krb5.conf-db1 krb5.conf-lmdb
+
+noinst_SCRIPTS = have-db
+
+check_SCRIPTS = loaddump-db add-modify-delete check-dbinfo check-aliases
+
+TESTS = $(check_SCRIPTS)
+
+do_subst = sed -e 's,[@]srcdir[@],$(srcdir),g' \
+ -e 's,[@]top_builddir[@],$(top_builddir),g' \
+ -e 's,[@]objdir[@],$(top_builddir)/tests/db,g' \
+ -e 's,[@]default_db_type[@],$(db_type),g' \
+ -e 's,[@]db_type_preference[@],$(db_type_preference),g' \
+ -e 's,[@]EGREP[@],$(EGREP),g'
+
+loaddump-db: loaddump-db.in Makefile
+ $(do_subst) < $(srcdir)/loaddump-db.in > loaddump-db.tmp
+ chmod +x loaddump-db.tmp
+ mv loaddump-db.tmp loaddump-db
+
+add-modify-delete: add-modify-delete.in Makefile
+ $(do_subst) < $(srcdir)/add-modify-delete.in > add-modify-delete.tmp
+ chmod +x add-modify-delete.tmp
+ mv add-modify-delete.tmp add-modify-delete
+
+check-dbinfo: check-dbinfo.in Makefile
+ $(do_subst) < $(srcdir)/check-dbinfo.in > check-dbinfo.tmp
+ chmod +x check-dbinfo.tmp
+ mv check-dbinfo.tmp check-dbinfo
+
+check-aliases: check-aliases.in Makefile
+ $(do_subst) < $(srcdir)/check-aliases.in > check-aliases.tmp
+ chmod +x check-aliases.tmp
+ mv check-aliases.tmp check-aliases
+
+have-db: have-db.in Makefile
+ $(do_subst) < $(srcdir)/have-db.in > have-db.tmp
+ chmod +x have-db.tmp
+ mv have-db.tmp have-db
+
+krb5.conf: krb5.conf.in Makefile
+ $(do_subst) -e 's,[@]type[@],,g' < $(srcdir)/krb5.conf.in > krb5.conf.tmp
+ mv krb5.conf.tmp krb5.conf
+
+krb5.conf-sqlite: krb5.conf.in Makefile
+ $(do_subst) -e 's,[@]type[@],sqlite:,g' < $(srcdir)/krb5.conf.in > krb5.conf-sqlite.tmp
+ mv krb5.conf-sqlite.tmp krb5.conf-sqlite
+
+krb5.conf-db3: krb5.conf.in Makefile
+ $(do_subst) -e 's,[@]type[@],db3:,g' < $(srcdir)/krb5.conf.in > krb5.conf-db3.tmp
+ mv krb5.conf-db3.tmp krb5.conf-db3
+
+krb5.conf-db1: krb5.conf.in Makefile
+ $(do_subst) -e 's,[@]type[@],db1:,g' < $(srcdir)/krb5.conf.in > krb5.conf-db1.tmp
+ mv krb5.conf-db1.tmp krb5.conf-db1
+
+krb5.conf-lmdb: krb5.conf.in Makefile
+ $(do_subst) -e 's,[@]type[@],lmdb:,g' < $(srcdir)/krb5.conf.in > krb5.conf-lmdb.tmp
+ mv krb5.conf-lmdb.tmp krb5.conf-lmdb
+
+krb5-mit.conf: krb5-mit.conf.in Makefile
+ $(do_subst) < $(srcdir)/krb5-mit.conf.in > krb5-mit.conf.tmp
+ mv krb5-mit.conf.tmp krb5-mit.conf
+
+
+CLEANFILES= \
+ $(TESTS) \
+ have-db \
+ db-dump* \
+ dbinfo.out \
+ current-db* \
+ out-text-dump* \
+ out-current-* \
+ mkey.file* \
+ krb5.conf krb5.conf.tmp \
+ krb5.conf-sqlite krb5.conf-sqlite.tmp \
+ krb5.conf-db3 krb5.conf-db3.tmp \
+ krb5.conf-db1 krb5.conf-db1.tmp \
+ krb5.conf-lmdb krb5.conf-lmdb.tmp \
+ krb5-mit.conf krb5-mit.conf.tmp \
+ tempfile \
+ log.current-db* \
+ heimdal-db* \
+ messages.log
+
+EXTRA_DIST = \
+ NTMakefile \
+ check-aliases.in \
+ check-dbinfo.in \
+ loaddump-db.in \
+ add-modify-delete.in \
+ have-db.in \
+ krb5.conf.in \
+ krb5-mit.conf.in \
+ text-dump-0.7 \
+ text-dump-known-ext \
+ text-dump-no-ext \
+ text-dump-unknown-ext
+
diff --git a/third_party/heimdal/tests/db/NTMakefile b/third_party/heimdal/tests/db/NTMakefile
new file mode 100644
index 0000000..fbbc303
--- /dev/null
+++ b/third_party/heimdal/tests/db/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=tests\db
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/tests/db/add-modify-delete.in b/third_party/heimdal/tests/db/add-modify-delete.in
new file mode 100644
index 0000000..7f3a819
--- /dev/null
+++ b/third_party/heimdal/tests/db/add-modify-delete.in
@@ -0,0 +1,140 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+srcdir="@srcdir@"
+objdir="@objdir@"
+EGREP="@EGREP@"
+
+default_db_type=@default_db_type@
+db_type=${1:-${default_db_type}}
+
+# If there is no useful db support compiled in, disable test
+./have-db || exit 77
+
+R=EXAMPLE.ORG
+
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r $R"
+iproplog="${TESTS_ENVIRONMENT} ../../lib/kadm5/iprop-log"
+
+KRB5_CONFIG="${objdir}/krb5.conf-${db_type}"
+export KRB5_CONFIG
+
+rm -f current-db*
+rm -f log.current-db*
+rm -f out-*
+rm -f mkey.file*
+
+echo init database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ EXAMPLE.ORG || exit 1
+
+echo test add
+${kadmin} add -r --use-defaults foo || exit 1
+${kadmin} list '*' > /dev/null || exit 1
+${kadmin} list '*' | ${EGREP} '^foo$' > /dev/null || exit 1
+
+echo "test add (double)"
+${kadmin} add -r --use-defaults foo 2>/dev/null && exit 1
+
+echo test rename
+${kadmin} rename foo bar
+${kadmin} list '*' | ${EGREP} '^foo$' > /dev/null && exit 1
+${kadmin} list '*' | ${EGREP} '^bar$' > /dev/null || exit 1
+
+echo test delete
+${kadmin} delete bar || exit 1
+${kadmin} list '*' | ${EGREP} '^bar$' > /dev/null && exit 1
+
+echo "test delete (double)"
+${kadmin} delete bar 2> /dev/null && exit 1
+
+echo "creating sample user"
+${kadmin} add -r --use-defaults foo || exit 1
+${kadmin} get foo > tempfile || exit 1
+echo checking principal
+${EGREP} " *Principal: foo@EXAMPLE.ORG$" tempfile > /dev/null || exit 1
+echo checking kvno
+${EGREP} " *Kvno: 1$" tempfile > /dev/null || exit 1
+echo checking failed login count
+${EGREP} " *Failed login count: 0$" tempfile > /dev/null || exit 1
+echo checking modifier
+${EGREP} " *Modifier: kadmin/admin@EXAMPLE.ORG$" tempfile > /dev/null || exit 1
+echo checking attributes
+${EGREP} " *Attributes: $" tempfile > /dev/null || exit 1
+echo checking renew time
+${EGREP} " *Max renewable life: 1 week$" tempfile > /dev/null || exit 1
+
+echo modifing renewable-life
+${kadmin} modify --max-renewable-life=2months foo
+echo checking renew time
+${kadmin} get foo > tempfile || exit 1
+${EGREP} " *Max renewable life: 2 months$" tempfile > /dev/null || exit 1
+
+echo "creating sample server"
+${kadmin} add -r --use-defaults host/datan.example.org || exit 1
+${kadmin} get host/datan.example.org > tempfile || exit 1
+echo checking principal
+${EGREP} " *Principal: host/datan.example.org@EXAMPLE.ORG$" tempfile > /dev/null || exit 1
+echo checking kvno
+${EGREP} " *Kvno: 1$" tempfile > /dev/null || exit 1
+
+echo "iprop-log dump"
+${iproplog} dump > /dev/null || exit 1
+echo "iprop-log last-version"
+${iproplog} last-version > /dev/null || exit 1
+
+echo "check iprop replay"
+
+${kadmin} dump out-current-db || exit 1
+sort out-current-db > out-current-db-sort
+
+rm -f current-db*
+
+echo "replaying"
+${iproplog} replay > /dev/null || exit 1
+
+${kadmin} dump out-current-db2 || exit 1
+sort out-current-db2 > out-current-db2-sort
+
+# XXX database should really be the same afterward... :(
+# cmp out-current-db-sort out-current-db2-sort || exit 1
+
+
+
+exit 0
diff --git a/third_party/heimdal/tests/db/check-aliases.in b/third_party/heimdal/tests/db/check-aliases.in
new file mode 100644
index 0000000..b5a1069
--- /dev/null
+++ b/third_party/heimdal/tests/db/check-aliases.in
@@ -0,0 +1,134 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+srcdir="@srcdir@"
+objdir="@objdir@"
+EGREP="@EGREP@"
+
+default_db_type=@default_db_type@
+db_type=${1:-${default_db_type}}
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+# If there is no useful db support compiled in, disable test
+../db/have-db || exit 77
+
+R=TEST.H5L.SE
+
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l"
+
+KRB5_CONFIG="${objdir}/krb5.conf-${db_type}"
+export KRB5_CONFIG
+
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+echo "Adding foo"
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} modify --alias=foo-alias1@${R} --alias=foo-alias2@${R} foo@${R} || exit 1
+
+echo "Adding bar"
+${kadmin} add -p foo --use-defaults bar@${R} || exit 1
+${kadmin} add_alias bar@${R} bar-alias1@${R} bar-alias2@${R} || exit 1
+${kadmin} add_alias bar@${R} bar-alias4@${R} bar-alias3@${R} || exit 1
+${kadmin} get -o principal bar@${R} | grep "Principal:.bar@${R}" >/dev/null || exit 1
+${kadmin} get -o principal bar-alias1@${R} | grep "Principal:.bar@${R}" >/dev/null || exit 1
+${kadmin} get -o aliases bar@${R} | grep "Aliases:.*bar-alias1@${R}" >/dev/null || exit 1
+${kadmin} get -o aliases bar@${R} | grep "Aliases:.*bar-alias2@${R}" >/dev/null || exit 1
+${kadmin} get -o aliases bar@${R} | grep "Aliases:.*bar-alias3@${R}" >/dev/null || exit 1
+${kadmin} get -o aliases bar@${R} | grep "Aliases:.*bar-alias4@${R}" >/dev/null || exit 1
+
+echo "Baz does not exists"
+
+echo "Checking dup keys"
+${kadmin} modify --alias=foo-alias1@${R} bar@${R} 2>/dev/null && exit 1
+${kadmin} modify --alias=foo@${R} bar@${R} 2>/dev/null && exit 1
+${kadmin} modify --alias=foo@${R} baz@${R} 2>/dev/null && exit 1
+
+echo "Rename over dup key"
+${kadmin} rename bar${R} foo-alias1${R} 2>/dev/null && exit 1
+${kadmin} rename bar${R} foo${R} 2>/dev/null && exit 1
+${kadmin} rename baz${R} foo-alias1${R} 2>/dev/null && exit 1
+${kadmin} rename baz${R} foo${R} 2>/dev/null && exit 1
+
+echo "Delete alias (must fail)"
+${kadmin} delete foo-alias1${R} 2>/dev/null && exit 1
+${kadmin} delete bar-alias1${R} 2>/dev/null && exit 1
+${kadmin} delete baz-alias1${R} 2>/dev/null && exit 1
+
+echo "Delete aliases with del_alias (must succeed)"
+${kadmin} del_alias bar-alias2@${R} bar-alias3@${R} bar-alias4@${R} || exit 1
+${kadmin} get -o principal bar@${R} | grep "Principal:.bar@${R}" >/dev/null || exit 1
+${kadmin} get -o aliases bar@${R} | grep "Aliases:.*bar-alias1@${R}" >/dev/null || exit 1
+${kadmin} get -o aliases bar@${R} | grep "Aliases:.*bar-alias2@${R}" >/dev/null && exit 1
+${kadmin} get -o aliases bar@${R} | grep "Aliases:.*bar-alias3@${R}" >/dev/null && exit 1
+${kadmin} get -o aliases bar@${R} | grep "Aliases:.*bar-alias4@${R}" >/dev/null && exit 1
+
+echo "Delete"
+${kadmin} delete bar@${R} || exit 1
+${kadmin} delete bar@${R} 2>/dev/null && exit 1
+${kadmin} delete baz@${R} 2>/dev/null && exit 1
+
+echo "Add alias to deleted name"
+${kadmin} modify --alias=bar-alias1@${R} foo@${R} || exit 1
+${kadmin} modify --alias=bar@${R} foo@${R} || exit 1
+${kadmin} modify --alias=bar@${R} --alias=baz@${R} foo@${R} || exit 1
+${kadmin} get -o principal foo@${R} | grep "Principal:.foo@${R}" >/dev/null || exit 1
+${kadmin} get -o principal bar@${R} | grep "Principal:.foo@${R}" >/dev/null || exit 1
+${kadmin} get -o principal baz@${R} | grep "Principal:.foo@${R}" >/dev/null || exit 1
+${kadmin} get -o aliases foo@${R} |grep "Aliases:.*bar@${R}" >/dev/null || exit 1
+${kadmin} get -o aliases foo@${R} |grep "Aliases:.*baz@${R}" >/dev/null || exit 1
+${kadmin} get -o aliases foo@${R} |grep "Aliases:.*bar-alias1@${R}" >/dev/null && exit 1
+${kadmin} get bar-alias1@${R} 2>/dev/null && exit 1
+
+echo "Rename over self alias key"
+${kadmin} rename foo@${R} foo-alias1@${R} 2>/dev/null && exit 1
+${kadmin} modify --alias= foo@${R} || exit 1
+${kadmin} rename foo@${R} foo-alias1@${R} || exit 1
+${kadmin} modify --alias=foo foo-alias1@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+exit 0
diff --git a/third_party/heimdal/tests/db/check-dbinfo.in b/third_party/heimdal/tests/db/check-dbinfo.in
new file mode 100644
index 0000000..0949051
--- /dev/null
+++ b/third_party/heimdal/tests/db/check-dbinfo.in
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+default_db_type=@default_db_type@
+db_type=${1:-${default_db_type}}
+
+KRB5_CONFIG="${objdir}/krb5.conf-${db_type}"
+export KRB5_CONFIG
+
+../../lib/hdb/test_dbinfo > dbinfo.out || exit 1
+
+../../lib/hdb/test_mkey --mkey-file="${srcdir}/../../lib/hdb/data-mkey.mit.des3.le" || exit 1
+../../lib/hdb/test_mkey --mkey-file="${srcdir}/../../lib/hdb/data-mkey.mit.des3.be" || exit 1
+
+
+exit 0
diff --git a/third_party/heimdal/tests/db/have-db.in b/third_party/heimdal/tests/db/have-db.in
new file mode 100644
index 0000000..917ceb4
--- /dev/null
+++ b/third_party/heimdal/tests/db/have-db.in
@@ -0,0 +1,72 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+top_builddir="@top_builddir@"
+
+. ${top_builddir}/tests/bin/setup-env
+
+if [ $# != 0 ]; then
+ for type in "$@"; do
+ for have_type in \
+ `${kdc} --builtin-hdb | sed 's/^builtin hdb backends: //'`; do
+ if [ "$type" = "$have_type" ]; then
+ exit 0
+ fi
+ done
+ done
+ exit 1
+fi
+
+list=`${kdc} --builtin-hdb | sed 's/^builtin hdb backends: //'`
+oldIFS="$IFS"
+IPS=,
+set - ${list}
+IFS="$oldIFS"
+
+while [ $# != 0 ] ; do
+ case $1 in
+ db:*) exit 0 ;;
+ db1:*) exit 0 ;;
+ gdbm:*) exit 0 ;;
+ db4:*) exit 0 ;;
+ db3:*) exit 0 ;;
+ lmdb:*) exit 0 ;;
+ sqlite:*) exit 0 ;;
+ esac
+ shift
+done
+
+exit 1
diff --git a/third_party/heimdal/tests/db/krb5-mit.conf.in b/third_party/heimdal/tests/db/krb5-mit.conf.in
new file mode 100644
index 0000000..99ffe4a
--- /dev/null
+++ b/third_party/heimdal/tests/db/krb5-mit.conf.in
@@ -0,0 +1,18 @@
+[libdefaults]
+ default_realm = EXAMPLE.ORG
+
+[kdc]
+ database = {
+ label = {
+ realm = EXAMPLE.ORG
+ dbname = mit-db:@srcdir@/mit-db
+ mkey_file = @srcdir@/mit-db-master-stash
+ log_file = @objdir@/current.log
+ }
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ default = 0-/FILE:@objdir@/messages.log
diff --git a/third_party/heimdal/tests/db/krb5.conf.in b/third_party/heimdal/tests/db/krb5.conf.in
new file mode 100644
index 0000000..f5324cb
--- /dev/null
+++ b/third_party/heimdal/tests/db/krb5.conf.in
@@ -0,0 +1,32 @@
+[libdefaults]
+ default_realm = EXAMPLE.ORG
+
+[realms]
+ EXAMPLE.ORG = {
+ kdc = localhost
+ }
+
+[kdc]
+ database = {
+ label = {
+ realm = LABEL.TEST.H5L.SE
+ dbname = @type@@objdir@/label-db
+ mkey_file = @objdir@/mkey.file
+ log_file = @objdir@/current.log
+ }
+ label2 = {
+ dbname = @type@@objdir@/lable2-db
+ realm = LABEL2.TEST.H5L.SE
+ mkey_file = @objdir@/mkey2.file
+ log_file = @objdir@/current.log
+ }
+ dbname = @type@@objdir@/current-db
+ realm = EXAMPLE.ORG
+ mkey_file = @objdir@/mkey.file
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ default = 0-/FILE:@objdir@/messages.log
diff --git a/third_party/heimdal/tests/db/loaddump-db.in b/third_party/heimdal/tests/db/loaddump-db.in
new file mode 100644
index 0000000..00d8186
--- /dev/null
+++ b/third_party/heimdal/tests/db/loaddump-db.in
@@ -0,0 +1,134 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+# If there is no useful db support compiled in, disable test
+./have-db || exit 77
+
+R=EXAMPLE.ORG
+
+kadmin="../../kadmin/kadmin -l -r $R"
+kstash="../../kdc/kstash"
+hprop="../../kdc/hprop"
+hpropd="../../kdc/hpropd"
+
+default_db_type=@default_db_type@
+db_type=${1:-${default_db_type}}
+
+propdb="${hprop} --database=${db_type}:./current-db -n"
+propddb="${hpropd} --database=${db_type}:./current-db -n"
+
+KRB5_CONFIG="${objdir}/krb5.conf-${db_type}"
+export KRB5_CONFIG
+
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ EXAMPLE.ORG || exit 1
+
+# check that we can dump and load ourself
+${kadmin} dump out-current-db || exit 1
+sort out-current-db > out-current-db-sort
+${kadmin} load out-current-db || exit 1
+${kadmin} dump out-current-db2 || exit 1
+sort out-current-db2 > out-current-db2-sort
+cmp out-current-db-sort out-current-db2-sort || exit 1
+
+rm -f current-db*
+
+# check with no extensions
+${kadmin} load ${srcdir}/text-dump-0.7 || exit 1
+${propdb} > db-dump.tmp|| exit 1
+rm -f current-db*
+${propddb} < db-dump.tmp || exit 1
+${kadmin} dump | sort | sed 's/[0-9]* -$//' > out-text-dump-0.7 || exit 1
+sort < ${srcdir}/text-dump-0.7 | \
+ sed 's/[0-9]*$//' > out-text-dump-0.7-orig || exit 1
+cmp out-text-dump-0.7-orig out-text-dump-0.7 || exit 1
+
+# check with no extensions
+${kadmin} load ${srcdir}/text-dump-no-ext || exit 1
+${propdb} > db-dump.tmp || exit 1
+${propddb} < db-dump.tmp || exit 1
+${kadmin} dump | sort | \
+ awk '{$11=""; print;}' > out-text-dump-no-ext || exit 1
+sort < ${srcdir}/text-dump-no-ext | \
+ awk '{$11=""; print;}' > out-text-dump-no-ext-orig || exit 1
+cmp out-text-dump-no-ext-orig out-text-dump-no-ext || exit 1
+
+# check with known extensions
+${kadmin} load ${srcdir}/text-dump-known-ext || exit 1
+${propdb} > db-dump.tmp || exit 1
+${propddb} < db-dump.tmp || exit 1
+${kadmin} dump | sort | \
+ awk '{$11=""; print;}' > out-text-dump-known-ext || exit 1
+sort < ${srcdir}/text-dump-known-ext | \
+ awk '{$11=""; print;}' > out-text-dump-known-ext-orig || exit 1
+cmp out-text-dump-known-ext-orig out-text-dump-known-ext || exit 1
+
+# check with unknown extensions
+${kadmin} load ${srcdir}/text-dump-unknown-ext || exit 1
+${propdb} > db-dump.tmp || exit 1
+${propddb} < db-dump.tmp || exit 1
+${kadmin} dump | sort | \
+ awk '{$11=""; print;}' > out-text-dump-unknown-ext || exit 1
+sort < ${srcdir}/text-dump-unknown-ext | \
+ awk '{$11=""; print;}' > out-text-dump-unknown-ext-orig || exit 1
+cmp out-text-dump-unknown-ext-orig out-text-dump-unknown-ext || exit 1
+
+${kstash} -e aes256-cts-hmac-sha1-96 --random-key -k ./mkey.file >/dev/null 2>/dev/null || exit 1
+
+# remove masterkey
+${kadmin} load ${srcdir}/text-dump-0.7 || exit 1
+${propdb} > db-dump.tmp|| exit 1
+${propddb} < db-dump.tmp || exit 1
+${propdb} -m mkey.file -D > db-dump.tmp || exit 1
+mv mkey.file mkey.file.no || exit 1
+${propddb} < db-dump.tmp || exit 1
+${kadmin} dump | sort | \
+ awk '{$11=""; print;}' > out-text-dump-0.7 || exit 1
+sort < ${srcdir}/text-dump-unknown-ext | \
+ awk '{$11=""; print;}' > out-text-dump-0.7-orig || exit 1
+cmp out-text-dump-0.7 out-text-dump-0.7-orig || exit 1
+
+exit 0
diff --git a/third_party/heimdal/tests/db/text-dump-0.7 b/third_party/heimdal/tests/db/text-dump-0.7
new file mode 100644
index 0000000..4aff11d
--- /dev/null
+++ b/third_party/heimdal/tests/db/text-dump-0.7
@@ -0,0 +1,7 @@
+changepw/kerberos@EXAMPLE.ORG 1::3:2376E6A4C1D5456D:-::2:2376E6A4C1D5456D:-::1:2376E6A4C1D5456D:-::18:39C3D293A6B0CEE734C7874764A8B5449F348AC00A6EA94F7451D07BE31EF239:-::16:108373F74F105875DCCE866B160886C7BC6780E526D0DAEA:-::23:D279B73431AA349F63594EA800397195:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 639 20050728203748:743456:2
+default@EXAMPLE.ORG 0::3:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::2:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::1:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::18:AF401411D3F29C204611A9BA1EF54AEDEC43A01B0123C57B994B2EE104E7F127:3/"EXAMPLE.ORGdefault"::16:02401CAD7A92760E464025760BCD3BE5DF616DD5A798C719:3/"EXAMPLE.ORGdefault"::23:31D6CFE0D16AE931B73C59D7E0C089C0:3/"EXAMPLE.ORGdefault" 20050728203748:kadmin/admin@EXAMPLE.ORG - - - - 86400 604800 254 20050728203748:863727:0
+kadmin/admin@EXAMPLE.ORG 1::3:2FCD23DCC2C726CE:-::2:2FCD23DCC2C726CE:-::1:2FCD23DCC2C726CE:-::18:1675F5E5BAD61428DE51F7C8EDCD53F23426D90F4F0BB4F9C73514D317E0482A:-::16:C79D6B0879B6ABADCE4A9B436B5B4A4F792679CDBC7F5D10:-::23:265C712FED225A85567BAF8CD9A4C4ED:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 382 20050728203748:682995:2
+kadmin/changepw@EXAMPLE.ORG 1::3:57A132CB9D7F4F37:-::2:57A132CB9D7F4F37:-::1:57A132CB9D7F4F37:-::18:B8252C9E3EC99969053631C238BBF88A0AAA082A8F1C4ED8D1729170C79519B8:-::16:10CE89987A1FD0986E6D836DB3F473E04C648C34F17CBCE3:-::23:A6D2BCA6F54B1C1AA5E875F116EEDE82:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 300 300 867 20050728203748:623022:2
+kadmin/hprop@EXAMPLE.ORG 1::3:76DC5751EFE52931:-::2:76DC5751EFE52931:-::1:76DC5751EFE52931:-::18:9B4D02F7D74790AB929E607BE5940CFF66801C237840EE968FDEFD7ED1387350:-::16:4CD575703D197F2991D5233704BAE379DF4FFBE616256762:-::23:E3D49F7E3462823492F33FAD8F0A754F:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 383 20050728203748:803541:2
+krbtgt/EXAMPLE.ORG@EXAMPLE.ORG 1::3:C219830E0E73DCEC:-::2:C219830E0E73DCEC:-::1:C219830E0E73DCEC:-::18:56CD702EE58B6EF4CAF758DA0BA1B92B21EFC1D2E9FCC0785009BC391F8571B8:-::16:29E9A2F45B2561D5B592C1070708B94A894AE046D091CE7C:-::23:30A2FB86CDC17B4EC625DC66C47AAF37:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 86400 2592000 126 20050728203748:560639:2
+lha@EXAMPLE.ORG 1::3:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::2:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::1:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::18:96653BEA5A46E5DF97D535C6C49F007E02F0E56B21F498C14F8C014871FE9889:3/"EXAMPLE.ORGlha"::16:7545202640A81304AE987F231FCB1F625D02CE7FF8A4ABEA:3/"EXAMPLE.ORGlha"::23:AC8E657F83DF82BEEA5D43BDAF7800CC:3/"EXAMPLE.ORGlha" 20050728203752:kadmin/admin@EXAMPLE.ORG 20050728203758:kadmin/admin@EXAMPLE.ORG - - - 86400 604800 126 20050728203752:988968:1
diff --git a/third_party/heimdal/tests/db/text-dump-known-ext b/third_party/heimdal/tests/db/text-dump-known-ext
new file mode 100644
index 0000000..8c3649c
--- /dev/null
+++ b/third_party/heimdal/tests/db/text-dump-known-ext
@@ -0,0 +1,7 @@
+changepw/kerberos@EXAMPLE.ORG 1::3:2376E6A4C1D5456D:-::2:2376E6A4C1D5456D:-::1:2376E6A4C1D5456D:-::18:39C3D293A6B0CEE734C7874764A8B5449F348AC00A6EA94F7451D07BE31EF239:-::16:108373F74F105875DCCE866B160886C7BC6780E526D0DAEA:-::23:D279B73431AA349F63594EA800397195:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 639 20050728203748:743456:2 -
+default@EXAMPLE.ORG 0::3:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::2:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::1:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::18:AF401411D3F29C204611A9BA1EF54AEDEC43A01B0123C57B994B2EE104E7F127:3/"EXAMPLE.ORGdefault"::16:02401CAD7A92760E464025760BCD3BE5DF616DD5A798C719:3/"EXAMPLE.ORGdefault"::23:31D6CFE0D16AE931B73C59D7E0C089C0:3/"EXAMPLE.ORGdefault" 20050728203748:kadmin/admin@EXAMPLE.ORG - - - - 86400 604800 254 20050728203748:863727:0 -
+kadmin/admin@EXAMPLE.ORG 1::3:2FCD23DCC2C726CE:-::2:2FCD23DCC2C726CE:-::1:2FCD23DCC2C726CE:-::18:1675F5E5BAD61428DE51F7C8EDCD53F23426D90F4F0BB4F9C73514D317E0482A:-::16:C79D6B0879B6ABADCE4A9B436B5B4A4F792679CDBC7F5D10:-::23:265C712FED225A85567BAF8CD9A4C4ED:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 382 20050728203748:682995:2 -
+kadmin/changepw@EXAMPLE.ORG 1::3:57A132CB9D7F4F37:-::2:57A132CB9D7F4F37:-::1:57A132CB9D7F4F37:-::18:B8252C9E3EC99969053631C238BBF88A0AAA082A8F1C4ED8D1729170C79519B8:-::16:10CE89987A1FD0986E6D836DB3F473E04C648C34F17CBCE3:-::23:A6D2BCA6F54B1C1AA5E875F116EEDE82:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 300 300 867 20050728203748:623022:2 -
+kadmin/hprop@EXAMPLE.ORG 1::3:76DC5751EFE52931:-::2:76DC5751EFE52931:-::1:76DC5751EFE52931:-::18:9B4D02F7D74790AB929E607BE5940CFF66801C237840EE968FDEFD7ED1387350:-::16:4CD575703D197F2991D5233704BAE379DF4FFBE616256762:-::23:E3D49F7E3462823492F33FAD8F0A754F:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 383 20050728203748:803541:2 -
+krbtgt/EXAMPLE.ORG@EXAMPLE.ORG 1::3:C219830E0E73DCEC:-::2:C219830E0E73DCEC:-::1:C219830E0E73DCEC:-::18:56CD702EE58B6EF4CAF758DA0BA1B92B21EFC1D2E9FCC0785009BC391F8571B8:-::16:29E9A2F45B2561D5B592C1070708B94A894AE046D091CE7C:-::23:30A2FB86CDC17B4EC625DC66C47AAF37:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 86400 2592000 126 20050728203748:560639:2 -
+lha@EXAMPLE.ORG 1::3:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::2:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::1:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::18:96653BEA5A46E5DF97D535C6C49F007E02F0E56B21F498C14F8C014871FE9889:3/"EXAMPLE.ORGlha"::16:7545202640A81304AE987F231FCB1F625D02CE7FF8A4ABEA:3/"EXAMPLE.ORGlha"::23:AC8E657F83DF82BEEA5D43BDAF7800CC:3/"EXAMPLE.ORGlha" 20050728203752:kadmin/admin@EXAMPLE.ORG 20050728203758:kadmin/admin@EXAMPLE.ORG - - - 86400 604800 126 20050728203752:988968:1 -
diff --git a/third_party/heimdal/tests/db/text-dump-no-ext b/third_party/heimdal/tests/db/text-dump-no-ext
new file mode 100644
index 0000000..8c3649c
--- /dev/null
+++ b/third_party/heimdal/tests/db/text-dump-no-ext
@@ -0,0 +1,7 @@
+changepw/kerberos@EXAMPLE.ORG 1::3:2376E6A4C1D5456D:-::2:2376E6A4C1D5456D:-::1:2376E6A4C1D5456D:-::18:39C3D293A6B0CEE734C7874764A8B5449F348AC00A6EA94F7451D07BE31EF239:-::16:108373F74F105875DCCE866B160886C7BC6780E526D0DAEA:-::23:D279B73431AA349F63594EA800397195:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 639 20050728203748:743456:2 -
+default@EXAMPLE.ORG 0::3:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::2:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::1:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::18:AF401411D3F29C204611A9BA1EF54AEDEC43A01B0123C57B994B2EE104E7F127:3/"EXAMPLE.ORGdefault"::16:02401CAD7A92760E464025760BCD3BE5DF616DD5A798C719:3/"EXAMPLE.ORGdefault"::23:31D6CFE0D16AE931B73C59D7E0C089C0:3/"EXAMPLE.ORGdefault" 20050728203748:kadmin/admin@EXAMPLE.ORG - - - - 86400 604800 254 20050728203748:863727:0 -
+kadmin/admin@EXAMPLE.ORG 1::3:2FCD23DCC2C726CE:-::2:2FCD23DCC2C726CE:-::1:2FCD23DCC2C726CE:-::18:1675F5E5BAD61428DE51F7C8EDCD53F23426D90F4F0BB4F9C73514D317E0482A:-::16:C79D6B0879B6ABADCE4A9B436B5B4A4F792679CDBC7F5D10:-::23:265C712FED225A85567BAF8CD9A4C4ED:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 382 20050728203748:682995:2 -
+kadmin/changepw@EXAMPLE.ORG 1::3:57A132CB9D7F4F37:-::2:57A132CB9D7F4F37:-::1:57A132CB9D7F4F37:-::18:B8252C9E3EC99969053631C238BBF88A0AAA082A8F1C4ED8D1729170C79519B8:-::16:10CE89987A1FD0986E6D836DB3F473E04C648C34F17CBCE3:-::23:A6D2BCA6F54B1C1AA5E875F116EEDE82:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 300 300 867 20050728203748:623022:2 -
+kadmin/hprop@EXAMPLE.ORG 1::3:76DC5751EFE52931:-::2:76DC5751EFE52931:-::1:76DC5751EFE52931:-::18:9B4D02F7D74790AB929E607BE5940CFF66801C237840EE968FDEFD7ED1387350:-::16:4CD575703D197F2991D5233704BAE379DF4FFBE616256762:-::23:E3D49F7E3462823492F33FAD8F0A754F:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 383 20050728203748:803541:2 -
+krbtgt/EXAMPLE.ORG@EXAMPLE.ORG 1::3:C219830E0E73DCEC:-::2:C219830E0E73DCEC:-::1:C219830E0E73DCEC:-::18:56CD702EE58B6EF4CAF758DA0BA1B92B21EFC1D2E9FCC0785009BC391F8571B8:-::16:29E9A2F45B2561D5B592C1070708B94A894AE046D091CE7C:-::23:30A2FB86CDC17B4EC625DC66C47AAF37:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 86400 2592000 126 20050728203748:560639:2 -
+lha@EXAMPLE.ORG 1::3:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::2:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::1:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::18:96653BEA5A46E5DF97D535C6C49F007E02F0E56B21F498C14F8C014871FE9889:3/"EXAMPLE.ORGlha"::16:7545202640A81304AE987F231FCB1F625D02CE7FF8A4ABEA:3/"EXAMPLE.ORGlha"::23:AC8E657F83DF82BEEA5D43BDAF7800CC:3/"EXAMPLE.ORGlha" 20050728203752:kadmin/admin@EXAMPLE.ORG 20050728203758:kadmin/admin@EXAMPLE.ORG - - - 86400 604800 126 20050728203752:988968:1 -
diff --git a/third_party/heimdal/tests/db/text-dump-unknown-ext b/third_party/heimdal/tests/db/text-dump-unknown-ext
new file mode 100644
index 0000000..8c3649c
--- /dev/null
+++ b/third_party/heimdal/tests/db/text-dump-unknown-ext
@@ -0,0 +1,7 @@
+changepw/kerberos@EXAMPLE.ORG 1::3:2376E6A4C1D5456D:-::2:2376E6A4C1D5456D:-::1:2376E6A4C1D5456D:-::18:39C3D293A6B0CEE734C7874764A8B5449F348AC00A6EA94F7451D07BE31EF239:-::16:108373F74F105875DCCE866B160886C7BC6780E526D0DAEA:-::23:D279B73431AA349F63594EA800397195:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 639 20050728203748:743456:2 -
+default@EXAMPLE.ORG 0::3:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::2:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::1:3B2A671585E93D6B:3/"EXAMPLE.ORGdefault"::18:AF401411D3F29C204611A9BA1EF54AEDEC43A01B0123C57B994B2EE104E7F127:3/"EXAMPLE.ORGdefault"::16:02401CAD7A92760E464025760BCD3BE5DF616DD5A798C719:3/"EXAMPLE.ORGdefault"::23:31D6CFE0D16AE931B73C59D7E0C089C0:3/"EXAMPLE.ORGdefault" 20050728203748:kadmin/admin@EXAMPLE.ORG - - - - 86400 604800 254 20050728203748:863727:0 -
+kadmin/admin@EXAMPLE.ORG 1::3:2FCD23DCC2C726CE:-::2:2FCD23DCC2C726CE:-::1:2FCD23DCC2C726CE:-::18:1675F5E5BAD61428DE51F7C8EDCD53F23426D90F4F0BB4F9C73514D317E0482A:-::16:C79D6B0879B6ABADCE4A9B436B5B4A4F792679CDBC7F5D10:-::23:265C712FED225A85567BAF8CD9A4C4ED:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 382 20050728203748:682995:2 -
+kadmin/changepw@EXAMPLE.ORG 1::3:57A132CB9D7F4F37:-::2:57A132CB9D7F4F37:-::1:57A132CB9D7F4F37:-::18:B8252C9E3EC99969053631C238BBF88A0AAA082A8F1C4ED8D1729170C79519B8:-::16:10CE89987A1FD0986E6D836DB3F473E04C648C34F17CBCE3:-::23:A6D2BCA6F54B1C1AA5E875F116EEDE82:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 300 300 867 20050728203748:623022:2 -
+kadmin/hprop@EXAMPLE.ORG 1::3:76DC5751EFE52931:-::2:76DC5751EFE52931:-::1:76DC5751EFE52931:-::18:9B4D02F7D74790AB929E607BE5940CFF66801C237840EE968FDEFD7ED1387350:-::16:4CD575703D197F2991D5233704BAE379DF4FFBE616256762:-::23:E3D49F7E3462823492F33FAD8F0A754F:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 3600 3600 383 20050728203748:803541:2 -
+krbtgt/EXAMPLE.ORG@EXAMPLE.ORG 1::3:C219830E0E73DCEC:-::2:C219830E0E73DCEC:-::1:C219830E0E73DCEC:-::18:56CD702EE58B6EF4CAF758DA0BA1B92B21EFC1D2E9FCC0785009BC391F8571B8:-::16:29E9A2F45B2561D5B592C1070708B94A894AE046D091CE7C:-::23:30A2FB86CDC17B4EC625DC66C47AAF37:- 20050728203748:kadmin/admin@EXAMPLE.ORG 20050728203748:kadmin/admin@EXAMPLE.ORG - - - 86400 2592000 126 20050728203748:560639:2 -
+lha@EXAMPLE.ORG 1::3:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::2:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::1:80AB08A261D6A82F:3/"EXAMPLE.ORGlha"::18:96653BEA5A46E5DF97D535C6C49F007E02F0E56B21F498C14F8C014871FE9889:3/"EXAMPLE.ORGlha"::16:7545202640A81304AE987F231FCB1F625D02CE7FF8A4ABEA:3/"EXAMPLE.ORGlha"::23:AC8E657F83DF82BEEA5D43BDAF7800CC:3/"EXAMPLE.ORGlha" 20050728203752:kadmin/admin@EXAMPLE.ORG 20050728203758:kadmin/admin@EXAMPLE.ORG - - - 86400 604800 126 20050728203752:988968:1 -
diff --git a/third_party/heimdal/tests/gss/Makefile.am b/third_party/heimdal/tests/gss/Makefile.am
new file mode 100644
index 0000000..2de36bf
--- /dev/null
+++ b/third_party/heimdal/tests/gss/Makefile.am
@@ -0,0 +1,103 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+noinst_DATA = krb5.conf new_clients_k5.conf mech
+
+SCRIPT_TESTS = check-basic check-gss check-gssmask check-context check-spnego check-ntlm check-negoex
+
+TESTS = $(SCRIPT_TESTS)
+
+check_SCRIPTS = $(SCRIPT_TESTS)
+
+port = 49188
+
+do_subst = srcdirabs=`cd "$(srcdir)"; pwd`; objdirabs=`pwd`; sed \
+ -e 's,[@]srcdir[@],$(srcdir),g' \
+ -e "s,[@]srcdirabs[@],$${srcdirabs},g" \
+ -e 's,[@]env_setup[@],$(top_builddir)/tests/bin/setup-env,g' \
+ -e 's,[@]port[@],$(port),g' \
+ -e 's,[@]objdir[@],$(top_builddir)/tests/gss,g' \
+ -e "s,[@]objdirabs[@],$${objdirabs},g"
+
+check-gss: check-gss.in Makefile
+ $(do_subst) < $(srcdir)/check-gss.in > check-gss.tmp && \
+ chmod +x check-gss.tmp && \
+ mv check-gss.tmp check-gss
+
+check-gssmask: check-gssmask.in Makefile
+ $(do_subst) < $(srcdir)/check-gssmask.in > check-gssmask.tmp && \
+ chmod +x check-gssmask.tmp && \
+ mv check-gssmask.tmp check-gssmask
+
+check-context: check-context.in Makefile
+ $(do_subst) < $(srcdir)/check-context.in > check-context.tmp && \
+ chmod +x check-context.tmp && \
+ mv check-context.tmp check-context
+
+check-spnego: check-spnego.in Makefile
+ $(do_subst) < $(srcdir)/check-spnego.in > check-spnego.tmp && \
+ chmod +x check-spnego.tmp && \
+ mv check-spnego.tmp check-spnego
+
+check-basic: check-basic.in Makefile
+ $(do_subst) < $(srcdir)/check-basic.in > check-basic.tmp && \
+ chmod +x check-basic.tmp && \
+ mv check-basic.tmp check-basic
+
+check-ntlm: check-ntlm.in Makefile
+ $(do_subst) < $(srcdir)/check-ntlm.in > check-ntlm.tmp && \
+ chmod +x check-ntlm.tmp && \
+ mv check-ntlm.tmp check-ntlm
+
+check-negoex: check-negoex.in Makefile
+ $(do_subst) < $(srcdir)/check-negoex.in > check-negoex.tmp && \
+ chmod +x check-negoex.tmp && \
+ mv check-negoex.tmp check-negoex
+
+krb5.conf: krb5.conf.in Makefile
+ $(do_subst) < $(srcdir)/krb5.conf.in > krb5.conf.tmp && \
+ mv krb5.conf.tmp krb5.conf
+
+new_clients_k5.conf: new_clients_k5.conf.in Makefile
+ $(do_subst) < $(srcdir)/new_clients_k5.conf.in > new_clients_k5.conf.tmp && \
+ mv new_clients_k5.conf.tmp new_clients_k5.conf
+
+mech: mech.in Makefile
+ $(do_subst) < $(srcdir)/mech.in > mech.tmp && \
+ mv mech.tmp mech
+
+CLEANFILES= \
+ $(TESTS) \
+ foopassword \
+ barpassword \
+ krb5ccfile \
+ krb5ccfile-ds \
+ server.keytab \
+ krb5.conf \
+ new_clients_k5.conf \
+ mech \
+ current-db* \
+ *.log \
+ tempfile \
+ check-basic.tmp \
+ check-gss.tmp \
+ check-gssmask.tmp \
+ check-spnego.tmp \
+ check-ntlm.tmp \
+ check-context.tmp
+
+EXTRA_DIST = \
+ NTMakefile \
+ check-basic.in \
+ check-gss.in \
+ check-gssmask.in \
+ check-spnego.in \
+ check-ntlm.in \
+ check-context.in \
+ check-negoex.in \
+ ntlm-user-file.txt \
+ krb5.conf.in \
+ include-krb5.conf \
+ new_clients_k5.conf.in \
+ mech.in
diff --git a/third_party/heimdal/tests/gss/NTMakefile b/third_party/heimdal/tests/gss/NTMakefile
new file mode 100644
index 0000000..c1ca7a2
--- /dev/null
+++ b/third_party/heimdal/tests/gss/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=tests\gss
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/tests/gss/check-basic.in b/third_party/heimdal/tests/gss/check-basic.in
new file mode 100644
index 0000000..c5151c4
--- /dev/null
+++ b/third_party/heimdal/tests/gss/check-basic.in
@@ -0,0 +1,219 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+env_setup="@env_setup@"
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+../db/have-db || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+nokeytab="FILE:no-such-keytab"
+cache="FILE:krb5ccfile"
+cache2="FILE:krb5ccfile2"
+nocache="FILE:no-such-cache"
+
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+
+acquire_cred="${TESTS_ENVIRONMENT} ../../lib/gssapi/test_acquire_cred"
+test_kcred="${TESTS_ENVIRONMENT} ../../lib/gssapi/test_kcred"
+test_add_store_cred="${TESTS_ENVIRONMENT} ../../lib/gssapi/test_add_store_cred"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+KRB5_KTNAME="${keytab}"
+export KRB5_KTNAME
+KRB5CCNAME="${cache}"
+export KRB5CCNAME
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+echo upw > ${objdir}/foopassword
+
+${kadmin} add -p upw --use-defaults user@${R} || exit 1
+${kadmin} add -p upw --use-defaults another@${R} || exit 1
+${kadmin} add -p p1 --use-defaults host/host.test.h5l.se@${R} || exit 1
+${kadmin} ext -k ${keytab} host/host.test.h5l.se@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo Starting kdc
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; cat messages.log; exit 1;" EXIT
+
+exitcode=0
+
+echo "initial ticket"
+${kinit} -c ${cache} --password-file=${objdir}/foopassword user@${R} || exitcode=1
+
+echo "copy ccache with gss_store_cred"
+# Note we test that the ccache used for storing is token-expanded
+${test_add_store_cred} --default --overwrite --env ${cache} "${cache2}%{null}" || exit 1
+${klist} -c ${cache2} || exit 1
+
+echo "keytab"
+${acquire_cred} \
+ --acquire-type=accept \
+ --acquire-name=host@host.test.h5l.se || exit 1
+
+echo "keytab w/ short-form name and name canon rules"
+${acquire_cred} \
+ --acquire-type=accept \
+ --acquire-name=host@host || exit 1
+
+echo "keytab w/o name"
+${acquire_cred} \
+ --acquire-type=accept || exit 1
+
+echo "keytab w/ wrong name"
+${acquire_cred} \
+ --acquire-type=accept --kerberos \
+ --acquire-name=host@host2.test.h5l.se 2>/dev/null && exit 1
+
+echo "init using keytab"
+${acquire_cred} \
+ --kerberos \
+ --acquire-type=initiate \
+ --acquire-name=host@host.test.h5l.se > /dev/null || exit 1
+
+echo "init using keytab (loop 10)"
+${acquire_cred} \
+ --kerberos \
+ --acquire-type=initiate \
+ --loops=10 \
+ --acquire-name=host@host.test.h5l.se > /dev/null || exit 1
+
+echo "init using keytab (loop 10, target)"
+${acquire_cred} \
+ --kerberos \
+ --acquire-type=initiate \
+ --loops=10 \
+ --target=host@host.test.h5l.se \
+ --acquire-name=host@host.test.h5l.se > /dev/null || exit 1
+
+echo "init using keytab (loop 10, kerberos)"
+${acquire_cred} \
+ --acquire-type=initiate \
+ --loops=10 \
+ --kerberos \
+ --acquire-name=host@host.test.h5l.se > /dev/null || exit 1
+
+echo "init using keytab (loop 10, target, kerberos)"
+${acquire_cred} \
+ --acquire-type=initiate \
+ --loops=10 \
+ --kerberos \
+ --target=host@host.test.h5l.se \
+ --acquire-name=host@host.test.h5l.se > /dev/null || exit 1
+
+echo "init using existing cc"
+${acquire_cred} \
+ --kerberos \
+ --name-type=user-name \
+ --acquire-type=initiate \
+ --acquire-name=user || exit 1
+
+KRB5CCNAME=${nocache}
+
+echo "fail init using existing cc"
+${acquire_cred} \
+ --kerberos \
+ --name-type=user-name \
+ --acquire-type=initiate \
+ --acquire-name=user 2>/dev/null && exit 1
+
+echo "use gss_krb5_ccache_name for user"
+${acquire_cred} \
+ --kerberos \
+ --name-type=user-name \
+ --ccache=${cache} \
+ --acquire-type=initiate \
+ --acquire-name=user >/dev/null || exit 1
+
+KRB5CCNAME=${cache}
+KRB5_KTNAME=${nokeytab}
+
+echo "kcred"
+${test_kcred} || exit 1
+
+${kdestroy} -c ${cache}
+
+KRB5_KTNAME="${keytab}"
+
+echo "init using keytab"
+${acquire_cred} \
+ --kerberos \
+ --acquire-type=initiate \
+ --acquire-name=host@host.test.h5l.se 2>/dev/null || exit 1
+
+echo "init using keytab (ccache)"
+${acquire_cred} \
+ --kerberos \
+ --acquire-type=initiate \
+ --ccache=${cache} \
+ --acquire-name=host@host.test.h5l.se 2>/dev/null || exit 1
+
+trap "" EXIT
+
+echo "killing kdc (${kdcpid})"
+kill ${kdcpid} 2> /dev/null
+
+exit $exitcode
diff --git a/third_party/heimdal/tests/gss/check-context.in b/third_party/heimdal/tests/gss/check-context.in
new file mode 100644
index 0000000..2b866d2
--- /dev/null
+++ b/third_party/heimdal/tests/gss/check-context.in
@@ -0,0 +1,582 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+env_setup="@env_setup@"
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+../db/have-db || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+nokeytab="FILE:no-such-keytab"
+cache="FILE:krb5ccfile"
+
+kinit="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cache ${afs_no_afslog}"
+kdestroy="${TESTS_ENVIRONMENT} ../../kuser/kdestroy -c $cache"
+klist="${TESTS_ENVIRONMENT} ../../kuser/heimtools klist -c $cache"
+kgetcred="${TESTS_ENVIRONMENT} ../../kuser/kgetcred -c $cache"
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r $R"
+kdc="${TESTS_ENVIRONMENT} ../../kdc/kdc --addresses=localhost -P $port"
+ktutil="${TESTS_ENVIRONMENT} ../../admin/ktutil"
+
+context="${TESTS_ENVIRONMENT} ../../lib/gssapi/test_context"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+KRB5CCNAME=${cache}
+export KRB5CCNAME
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+# add both lucid and lucid.test.h5l.se to simulate aliases
+${kadmin} add -p p1 --use-defaults host/lucid.test.h5l.se@${R} || exit 1
+${kadmin} ext -k ${keytab} host/lucid.test.h5l.se@${R} || exit 1
+
+${kadmin} add -p p1 --use-defaults host/ok-delegate.test.h5l.se@${R} || exit 1
+${kadmin} mod --attributes=+ok-as-delegate host/ok-delegate.test.h5l.se@${R} || exit 1
+${kadmin} ext -k ${keytab} host/ok-delegate.test.h5l.se@${R} || exit 1
+
+
+${kadmin} add -p p1 --use-defaults host/short@${R} || exit 1
+${kadmin} mod --alias=host/long.test.h5l.se@${R} host/short@${R} || exit 1
+# XXX ext should ext aliases too
+${kadmin} ext -k ${keytab} host/short@${R} || exit 1
+${ktutil} -k ${keytab} rename --no-delete host/short@${R} host/long.test.h5l.se@${R} || exit 1
+
+${kadmin} add -p kaka --use-defaults digest/${R}@${R} || exit 1
+
+${kadmin} add -p u1 --use-defaults user1@${R} || exit 1
+${kadmin} mod --alias=user1.alias user1@${R} || exit 1
+
+# Create a server principal with no AES
+${kadmin} add -p p1 --use-defaults host/no-aes.test.h5l.se@${R} || exit 1
+${kadmin} get host/no-aes.test.h5l.se@${R} > tempfile || exit 1
+${kadmin} del_enctype host/no-aes.test.h5l.se@${R} \
+ aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 || exit 1
+${kadmin} ext -k ${keytab} host/no-aes.test.h5l.se@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo u1 > ${objdir}/foopassword
+
+echo Starting kdc
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+echo "Test gss_acquire_cred_with_password" ; > messages.log
+${kdestroy}
+${context} --client-name=user1@${R} --client-password=u1 --mech-type=krb5 \
+ host@lucid.test.h5l.se || { eval "$testfailed"; }
+${klist} && { eval "$testfailed"; }
+# These must fail (because wrong password)
+${context} --client-name=user1@${R} --client-password=u2 --mech-type=krb5 \
+ host@lucid.test.h5l.se && { eval "$testfailed"; }
+${klist} && { eval "$testfailed"; }
+${context} --client-name=user1@${R} --client-password=u2 --mech-types='' \
+ --mech-type=krb5 host@lucid.test.h5l.se && { eval "$testfailed"; }
+${klist} && { eval "$testfailed"; }
+${context} --client-name=user1@${R} --client-password=u2 --mech-types=krb5 \
+ --mech-type=krb5 host@lucid.test.h5l.se && { eval "$testfailed"; }
+${klist} && { eval "$testfailed"; }
+${context} --client-name=user1@${R} --client-password=u2 --mech-types=all \
+ --mech-type=krb5 host@lucid.test.h5l.se && { eval "$testfailed"; }
+${klist} && { eval "$testfailed"; }
+${context} --client-name=user1@${R} --client-password=u2 \
+ --mech-types=krb5,ntlm --mech-type=krb5 host@lucid.test.h5l.se \
+ && { eval "$testfailed"; }
+# gss_acquire_cred_with_password() must not have side-effects
+${klist} && { eval "$testfailed"; }
+
+echo "Getting client initial tickets" ; > messages.log
+${kinit} --password-file=${objdir}/foopassword --forwardable user1@${R} || \
+ { eval "$testfailed"; }
+
+echo "======test unreadable/non existant keytab and its error message" ; > messages.log
+${context} --mech-type=krb5 host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+mv ${keytabfile} ${keytabfile}.no
+
+echo "checking non existant keytabfile (krb5)" ; > messages.log
+${context} --mech-type=krb5 host@lucid.test.h5l.se > test_context.log 2>&1 && \
+ { eval "$testfailed"; }
+echo "checking non existant keytabfile (spengo)" ; > messages.log
+${context} --mech-type=spnego --mech-types=spnego,krb5 \
+ host@lucid.test.h5l.se > test_context.log 2>&1 && \
+ { eval "$testfailed"; }
+
+mv ${keytabfile}.no ${keytabfile}
+
+echo "======test naming combinations"
+echo "plain" ; > messages.log
+${context} --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+echo "plain w/ short-form hostname" ; > messages.log
+${context} --name-type=hostbased-service host@lucid || \
+ { eval "$testfailed"; }
+echo "plain (krb5)" ; > messages.log
+${context} --name-type=krb5-principal-name host/lucid.test.h5l.se@${R} || \
+ { eval "$testfailed"; }
+echo "plain (krb5 realmless)" ; > messages.log
+${context} --name-type=krb5-principal-name host/lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+echo "plain (krb5 realmless short-form)" ; > messages.log
+${context} --name-type=krb5-principal-name host/lucid 2>/dev/null || \
+ { eval "$testfailed"; }
+echo "creating short-form princ"
+${kadmin} add -p p1 --use-defaults host/lucid@${R} || exit 1
+${kadmin} ext -k ${keytab} host/lucid@${R} || exit 1
+echo "dns canon on (long name) OFF, need dns_wrapper" ; > messages.log
+#${context} --dns-canon host@lucid.test.h5l.se || \
+# { eval "$testfailed"; }
+echo "dns canon off (long name)" ; > messages.log
+${context} --no-dns-canon host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+echo "dns canon off (short name)" ; > messages.log
+${context} --no-dns-canon host@lucid || \
+ { eval "$testfailed"; }
+echo "dns canon off (short name, krb5)" ; > messages.log
+${context} --no-dns-canon --name-type=krb5-principal-name host/lucid@${R} || \
+ { eval "$testfailed"; }
+echo "dns canon off (short name, krb5)" ; > messages.log
+${context} --no-dns-canon --name-type=krb5-principal-name host/lucid || \
+ { eval "$testfailed"; }
+
+echo "======test context building"
+for mech in krb5 krb5iov spnego spnegoiov; do
+ if [ "$mech" = "krb5iov" ] ; then
+ mech="krb5"
+ iov="--iov"
+ fi
+ if [ "$mech" = "spnegoiov" ] ; then
+ mech="spnego"
+ iov="--iov"
+ fi
+
+ echo "${mech} no-mutual ${iov}" ; > messages.log
+ ${context} --mech-type=${mech} \
+ --wrapunwrap ${iov} \
+ --localname=mapped_user1 \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+ echo "${mech} mutual ${iov}" ; > messages.log
+ ${context} --mech-type=${mech} \
+ --mutual \
+ --wrapunwrap ${iov} \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+ echo "${mech} delegate ${iov}" ; > messages.log
+ ${context} --mech-type=${mech} \
+ --delegate \
+ --wrapunwrap ${iov} \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+ echo "${mech} mutual delegate ${iov}" ; > messages.log
+ ${context} --mech-type=${mech} \
+ --mutual --delegate \
+ --wrapunwrap ${iov} \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+done
+
+echo "======test authz-data (krb5)"
+${context} --mech-type=krb5 \
+ --mutual \
+ --wrapunwrap \
+ --on-behalf-of=foo@BAR.TEST.H5L.SE \
+ --name-type=hostbased-service host@lucid.test.h5l.se ||
+ { eval "$testfailed"; }
+
+echo "======dce-style"
+for mech in krb5 krb5iov spnego; do
+ iov=""
+ if [ "$mech" = "krb5iov" ] ; then
+ mech="krb5"
+ iov="--iov"
+ fi
+ if [ "$mech" = "spnegoiov" ] ; then
+ mech="spnego"
+ iov="--iov"
+ fi
+
+ echo "${mech}: dce-style ${iov}" ; > messages.log
+ ${context} \
+ --mech-type=${mech} \
+ --mutual \
+ --dce-style \
+ --wrapunwrap ${iov} \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+done
+
+echo "======export-import-context"
+for mech in krb5 krb5iov spnego spnegoiov; do
+ iov=""
+ if [ "$mech" = "krb5iov" ] ; then
+ mech="krb5"
+ iov="--iov"
+ fi
+ if [ "$mech" = "spnegoiov" ] ; then
+ mech="spnego"
+ iov="--iov"
+ fi
+
+ echo "${mech}: export-import-context ${iov}" ; > messages.log
+ ${context} \
+ --mech-type=${mech} \
+ --mutual \
+ --export-import-context \
+ --wrapunwrap ${iov} \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+done
+
+echo "test gsskrb5_register_acceptor_identity (both positive and negative)"
+
+cp ${keytabfile} ${keytabfile}.new
+for mech in krb5 spnego; do
+ echo "${mech}: acceptor_identity positive" ; > messages.log
+ ${context} --gsskrb5-acceptor-identity=${keytabfile}.new \
+ --mech-type=$mech host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+ echo "${mech}: acceptor_identity positive (prefix)" ; > messages.log
+ ${context} --gsskrb5-acceptor-identity=FILE:${keytabfile}.new \
+ --mech-type=$mech host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+ echo "${mech}: acceptor_identity negative" ; > messages.log
+ ${context} --gsskrb5-acceptor-identity=${keytabfile}.foo \
+ --mech-type=$mech host@lucid.test.h5l.se 2>/dev/null && \
+ { eval "$testfailed"; }
+done
+
+rm ${keytabfile}.new
+
+echo "====== test PAC-based name canonicalization"
+
+${kdestroy}
+${kinit} --password-file=${objdir}/foopassword user1.alias@${R} || \
+ { eval "$testfailed"; }
+
+for mech in krb5 spnego; do
+ KRB5_CONFIG="${objdir}/new_clients_k5.conf" ${context} -v \
+ --mech-type=$mech host@lucid.test.h5l.se > name-canon.log || \
+ { eval "$testfailed"; }
+ grep "client name:" name-canon.log | grep "user1.alias@TEST.H5L.SE" > /dev/null && \
+ { echo "client name not canonicalized"; eval "$testfailed"; }
+ grep "client name:" name-canon.log | grep "user1@TEST.H5L.SE" > /dev/null || \
+ { echo "wrong client name"; eval "$testfailed"; }
+done
+
+echo "====== test channel-bindings."
+
+for mech in krb5 spnego; do
+ echo "${mech}: initiator only bindings" ; > messages.log
+ ${context} -v --i-channel-bindings=abc \
+ --mech-type=$mech host@lucid.test.h5l.se > cbinding.log || \
+ { eval "$testfailed"; }
+ grep "sflags:" cbinding.log | grep "channel-bound" > /dev/null && \
+ { echo "channel-bound flag unexpected"; eval "$testfailed"; }
+
+ echo "${mech}: acceptor only bindings" ; > messages.log
+ ${context} -v --a-channel-bindings=abc \
+ --mech-type=$mech host@lucid.test.h5l.se > cbinding.log || \
+ { eval "$testfailed"; }
+ grep "sflags:" cbinding.log | grep "channel-bound" > /dev/null && \
+ { echo "channel-bound flag unexpected"; eval "$testfailed"; }
+
+ echo "${mech}: matching bindings" ; > messages.log
+ ${context} -v --i-channel-bindings=abc --a-channel-bindings=abc \
+ --mech-type=$mech host@lucid.test.h5l.se > cbinding.log || \
+ { eval "$testfailed"; }
+ grep "sflags:" cbinding.log | grep "channel-bound" > /dev/null || \
+ { echo "no channel-bound flag"; eval "$testfailed"; }
+
+ echo "${mech}: non matching bindings" ; > messages.log
+ ${context} --i-channel-bindings=abc --a-channel-bindings=xyz \
+ --mech-type=$mech host@lucid.test.h5l.se 2>/dev/null && \
+ { eval "$testfailed"; }
+
+ echo "${mech}: initiator only bindings (client-aware)" ; > messages.log
+ KRB5_CONFIG="${objdir}/new_clients_k5.conf" ${context} -v \
+ --i-channel-bindings=abc \
+ --mech-type=$mech host@lucid.test.h5l.se > cbinding.log || \
+ { eval "$testfailed"; }
+ grep "sflags:" cbinding.log | grep "channel-bound" > /dev/null && \
+ { echo "channel-bound flag unexpected"; eval "$testfailed"; }
+
+ echo "${mech}: acceptor only bindings (client-aware)" ; > messages.log
+ KRB5_CONFIG="${objdir}/new_clients_k5.conf" ${context} \
+ --a-channel-bindings=abc \
+ --mech-type=$mech host@lucid.test.h5l.se 2>/dev/null && \
+ { eval "$testfailed"; }
+
+ echo "${mech}: matching bindings (client-aware)" ; > messages.log
+ KRB5_CONFIG="${objdir}/new_clients_k5.conf" ${context} -v \
+ --i-channel-bindings=abc --a-channel-bindings=abc \
+ --mech-type=$mech host@lucid.test.h5l.se > cbinding.log || \
+ { eval "$testfailed"; }
+ grep "sflags:" cbinding.log | grep "channel-bound" > /dev/null || \
+ { echo "no channel-bound flag"; eval "$testfailed"; }
+
+ echo "${mech}: non matching bindings (client-aware)" ; > messages.log
+ KRB5_CONFIG="${objdir}/new_clients_k5.conf" ${context} \
+ --i-channel-bindings=abc --a-channel-bindings=xyz \
+ --mech-type=$mech host@lucid.test.h5l.se 2>/dev/null && \
+ { eval "$testfailed"; }
+
+done
+
+#echo "sasl-digest-md5"
+#${context} --mech-type=sasl-digest-md5 \
+# --name-type=hostbased-service \
+# host@lucid.test.h5l.se || \
+# { eval "$testfailed"; }
+
+
+echo "====== gss-api session key check"
+
+# this will break when oneone invents a cooler enctype then aes256-cts-hmac-sha1-96
+coolenctype="aes256-cts-hmac-sha1-96"
+limit_enctype="des3-cbc-sha1"
+
+echo "Getting client initial tickets" ; > messages.log
+${kinit} --password-file=${objdir}/foopassword user1@${R} || \
+ { eval "$testfailed"; }
+
+
+echo "Building context on cred w/o aes, but still ${coolenctype} session key" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --mutual-auth \
+ --session-enctype=${coolenctype} \
+ --name-type=hostbased-service host@no-aes.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "Building context on cred, check if its limited still" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --client-name=user1@${R} \
+ --limit-enctype="${limit_enctype}" \
+ --mutual-auth \
+ --name-type=hostbased-service host@no-aes.test.h5l.se || \
+ { eval "$testfailed"; }
+
+
+echo "====== ok-as-delegate"
+
+echo "Getting client initial tickets" ; > messages.log
+${kinit} --forwardable \
+ --password-file=${objdir}/foopassword user1@${R} || \
+ { eval "$testfailed"; }
+
+echo "ok-as-delegate not used" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --delegate \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "host without ok-as-delegate with policy-delegate" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --policy-delegate \
+ --server-no-delegate \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "ok-as-delegate used by policy" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --policy-delegate \
+ --name-type=hostbased-service host@ok-delegate.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "Getting client initial tickets with --ok-as-delgate" ; > messages.log
+${kinit} --ok-as-delegate --forwardable \
+ --password-file=${objdir}/foopassword user1@${R} || \
+ { eval "$testfailed"; }
+
+echo "policy delegate to non delegate host" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --policy-delegate \
+ --server-no-delegate \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "ok-as-delegate" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --delegate \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "======export/import cred"
+
+echo "export-import cred (krb5)" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --delegate \
+ --export-import-cred \
+ --name-type=hostbased-service host@ok-delegate.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "export-import cred (spnego)" ; > messages.log
+${context} \
+ --mech-type=spnego \
+ --delegate \
+ --export-import-cred \
+ --name-type=hostbased-service host@ok-delegate.test.h5l.se || \
+ { eval "$testfailed"; }
+
+
+echo "======time diffs between client and server"
+
+echo "Getting client initial ticket" ; > messages.log
+${kinit} --password-file=${objdir}/foopassword user1@${R} || \
+ { eval "$testfailed"; }
+
+echo "No time offset" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "Getting client initial ticket" ; > messages.log
+${kinit} --password-file=${objdir}/foopassword user1@${R} || \
+ { eval "$testfailed"; }
+
+echo "Server time offset" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --mutual-auth \
+ --server-time-offset=3600 \
+ --max-loops=3 \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "Server time offset (cached ?)" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --mutual-auth \
+ --server-time-offset=3600 \
+ --max-loops=2 \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "Getting client initial ticket" ; > messages.log
+${kinit} --password-file=${objdir}/foopassword user1@${R} || \
+ { eval "$testfailed"; }
+# Pre-poplute the cache since tgs-req will fail since our time is wrong
+${kgetcred} host/lucid.test.h5l.se@${R} || \
+ { eval "$testfailed"; }
+
+echo "Client time offset" ; > messages.log
+${context} \
+ --mech-type=krb5 \
+ --mutual-auth \
+ --client-time-offset=3600 \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+echo "Getting client initial tickets (use-referrals)" ; > messages.log
+${kinit} \
+ --password-file=${objdir}/foopassword \
+ --use-referrals user1@${R} || \
+ { eval "$testfailed"; }
+
+# XXX these tests really need to use somethat that resolve to something
+${context} \
+ --mech-type=krb5 \
+ host@short || \
+ { eval "$testfailed"; }
+
+${context} \
+ --mech-type=krb5 \
+ --name-type=krb5-principal-name host/short || \
+ { eval "$testfailed"; }
+
+${context} \
+ --mech-type=krb5 \
+ host@long.test.h5l.se || \
+ { eval "$testfailed"; }
+
+${context} \
+ --mech-type=krb5 \
+ --name-type=krb5-principal-name \
+ host/long.test.h5l.se || \
+ { eval "$testfailed"; }
+
+trap "" EXIT
+
+echo "killing kdc (${kdcpid})"
+kill ${kdcpid} 2> /dev/null
+
+exit 0
+
diff --git a/third_party/heimdal/tests/gss/check-gss.in b/third_party/heimdal/tests/gss/check-gss.in
new file mode 100644
index 0000000..f5254a1
--- /dev/null
+++ b/third_party/heimdal/tests/gss/check-gss.in
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+env_setup="@env_setup@"
+confdir="@confdir@"
+testdir="@testdir@"
+
+. ${env_setup}
+
+${TESTS_ENVIRONMENT} ${gsstool} help > /dev/null || exit 1
+${TESTS_ENVIRONMENT} ${gsstool} supported-mechanisms > /dev/null || exit 1
+${TESTS_ENVIRONMENT} ${gsstool} attrs-for-mech --all > /dev/null || exit 1
+${TESTS_ENVIRONMENT} ${gsstool} attrs-for-mech --mech=Kerberos > /dev/null || exit 1
+
+exit 0
+
+
diff --git a/third_party/heimdal/tests/gss/check-gssmask.in b/third_party/heimdal/tests/gss/check-gssmask.in
new file mode 100644
index 0000000..539e2e9
--- /dev/null
+++ b/third_party/heimdal/tests/gss/check-gssmask.in
@@ -0,0 +1,137 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+env_setup="@env_setup@"
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+../db/have-db || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r $R"
+kdc="${TESTS_ENVIRONMENT} ../../kdc/kdc --addresses=localhost -P $port"
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+
+gssmask="${TESTS_ENVIRONMENT} ../../appl/gssmask/gssmask"
+gssmaskn1="${gssmask} -p 8889 --spn=host/n1.test.h5l.se@${R} --logfile=n1.log"
+gssmaskn2="${gssmask} -p 8890 --spn=host/n2.test.h5l.se@${R} --logfile=n2.log"
+gssmaskn3="${gssmask} -p 8891 --spn=host/n3.test.h5l.se@${R} --logfile=n3.log"
+gssmaestro="../../appl/gssmask/gssmaestro"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+KRB5CCNAME=${cache}
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+# Test virtual principals, why not
+${kadmin} add_ns --key-rotation-epoch=now \
+ --key-rotation-period=15m \
+ --max-ticket-life=10d \
+ --max-renewable-life=20d \
+ --attributes= \
+ "_/test.h5l.se@${R}" || exit 1
+${kadmin} ext -k ${keytab} host/n1.test.h5l.se@${R} || exit 1
+${kadmin} ext -k ${keytab} host/n2.test.h5l.se@${R} || exit 1
+${kadmin} ext -k ${keytab} host/n3.test.h5l.se@${R} || exit 1
+
+${kadmin} add -p u1 --use-defaults user1@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo Starting kdc
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+exitcode=0
+
+echo "Starting client 1"
+${gssmaskn1} --moniker=n1 &
+n1pid=$!
+#echo $n1pid
+#xterm -display :0 -e g ${gssmaskn1} &
+#read x
+
+echo "Starting client 2"
+${gssmaskn2} --moniker=n2 &
+n2pid=$!
+
+echo "Starting client 3"
+${gssmaskn3} --moniker=n3 &
+n3pid=$!
+
+trap "kill ${kdcpid} ${n1pid} ${n2pid} ${n3pid} 2> /dev/null; echo signal killing kdc and maskar; exit 1;" EXIT
+
+sleep 10
+
+# --wrap-ext
+
+${gssmaestro} \
+ --slaves=localhost:8889 \
+ --slaves=localhost:8890 \
+ --slaves=localhost:8891 \
+ --principals=user1@${R}:u1 || exitcode=1
+
+trap "" EXIT
+
+echo "killing kdc and clients (${kdcpid}, ${n1pid}, ${n2pid}, ${n3pid})"
+kill ${kdcpid} ${n1pid} ${n2pid} ${n3pid} 2> /dev/null
+
+exit $exitcode
+
+
diff --git a/third_party/heimdal/tests/gss/check-negoex.in b/third_party/heimdal/tests/gss/check-negoex.in
new file mode 100644
index 0000000..063e0c1
--- /dev/null
+++ b/third_party/heimdal/tests/gss/check-negoex.in
@@ -0,0 +1,278 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+env_setup="@env_setup@"
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+R=TEST.H5L.SE
+
+port=@port@
+
+keytabfile="${objdir}/server.keytab-no"
+keytab="FILE:${keytabfile}-no"
+cache="FILE:krb5ccfile-no"
+cacheds="FILE:krb5ccfile-ds-no"
+
+context="${TESTS_ENVIRONMENT} ../../lib/gssapi/test_context"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+KRB5_KTNAME="${keytab}-no"
+export KRB5_KTNAME
+KRB5CCNAME="${cache}-no"
+export KRB5CCNAME
+unset NTLM_ACCEPTOR_CCACHE
+unset NTLM_USER_FILE
+
+GSSAPI_SPNEGO_NAME=host@host.test.h5l.se
+export GSSAPI_SPNEGO_NAME
+
+GSS_MECH_CONFIG="${objdir}/mech"
+export GSS_MECH_CONFIG
+
+> messages.log
+
+exitcode=0
+
+echo "======context building for negoex"
+
+for HOPS in 1 2 3 4 5
+do
+ echo "test_negoex_1 $HOPS hops"
+ ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+done
+
+for HOPS in 1 2 3 4 5
+do
+ echo "test_negoex_1 $HOPS hops early keys"
+ KEY=always ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+done
+
+HOPS=1
+echo "test_negoex_1 no keys"
+ KEY=never ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se 2>/dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 no optimistic token"
+ NEGOEX_NO_OPTIMISTIC_TOKEN=1 ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 initiator query fail, test_negoex_2 pass"
+ INIT_QUERY_FAIL=102 ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_2 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se 2>/dev/null || \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 acceptor query fail, test_negoex_2 pass"
+ ACCEPT_QUERY_FAIL=102 ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_2 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se 2>/dev/null || \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 acceptor exchange fail, test_negoex_2 pass"
+ ACCEPT_EXCHANGE_FAIL=102 ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_2 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se 2>/dev/null || \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 first mech initiator exchange fail"
+ INIT_EXCHANGE_FAIL=102 ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se 2>/dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 first mech initiator exchange fail, two hops"
+ HOPS=2 INIT_EXCHANGE_FAIL=102 ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se 2>/dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 first mech initiator exchange fail, two hops, early keys"
+ HOPS=2 KEY=always INIT_EXCHANGE_FAIL=102 ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se 2>/dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 first mech init_sec_context fail"
+ INIT_FAIL=102 ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se 2>/dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 first mech accept_sec_context fail"
+ HOPS=2 ACCEPT_FAIL=102 ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se 2>/dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 alert from acceptor to initiator"
+ HOPS=3 KEY=init-always ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+
+echo "test_negoex_1 alert from initiator to acceptor"
+ HOPS=4 KEY=accept-always ${context} \
+ --mech-type=spnego --ret-mech-type=test_negoex_1 \
+ --name-type=hostbased-service \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+
+unset GSS_MECH_CONFIG
+
+echo "======test context building for sanon-x25519"
+for mech in sanon-x25519 sanon-x25519iov spnego spnegoiov; do
+ iov=""
+ if [ "$mech" = "sanon-x25519iov" ] ; then
+ mech="sanon-x25519"
+ iov="--iov"
+ fi
+ if [ "$mech" = "spnegoiov" ] ; then
+ mech="spnego"
+ iov="--iov"
+ fi
+
+ echo "${mech} anon-flag ${iov}" ; > messages.log
+ ${context} --mech-type=${mech} \
+ --anonymous \
+ --ret-mech-type=sanon-x25519 \
+ --i-channel-bindings=negoex_sanon_test_h5l_se \
+ --a-channel-bindings=negoex_sanon_test_h5l_se \
+ --wrapunwrap ${iov} \
+ host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+ echo "${mech} anon-initiator ${iov}" ; > messages.log
+ ${context} --mech-type=${mech} \
+ --client-name=WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS \
+ --ret-mech-type=sanon-x25519 \
+ --i-channel-bindings=negoex_sanon_test_h5l_se \
+ --a-channel-bindings=negoex_sanon_test_h5l_se \
+ --wrapunwrap ${iov} \
+ host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+ echo "${mech} anon-acceptor ${iov}" ; > messages.log
+ ${context} --mech-type=${mech} \
+ --ret-mech-type=sanon-x25519 \
+ --i-channel-bindings=negoex_sanon_test_h5l_se \
+ --a-channel-bindings=negoex_sanon_test_h5l_se \
+ --wrapunwrap ${iov} \
+ WELLKNOWN@ANONYMOUS || \
+ { eval "$testfailed"; }
+done
+
+echo "======export-import-context for sanon-x25519"
+for mech in sanon-x25519 sanon-x25519iov spnego spnegoiov; do
+ iov=""
+ if [ "$mech" = "sanon-x25519iov" ] ; then
+ mech="sanon-x25519"
+ iov="--iov"
+ fi
+ if [ "$mech" = "spnegoiov" ] ; then
+ mech="spnego"
+ iov="--iov"
+ fi
+
+ echo "${mech}: export-import-context ${iov}" ; > messages.log
+ ${context} \
+ --mech-type=${mech} \
+ --anonymous \
+ --export-import-context \
+ --wrapunwrap ${iov} \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+ echo "${mech}: export-import-context ${iov} (split tokens)" ; > messages.log
+ ${context} \
+ --mech-type=${mech} \
+ --anonymous \
+ --export-import-context \
+ --wrapunwrap ${iov} \
+ --token-split=128 \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+done
+
+echo "======dce-style for sanon-x25519"
+for mech in spnego spnegoiov; do
+ iov=""
+ if [ "$mech" = "spnegoiov" ] ; then
+ mech="spnego"
+ iov="--iov"
+ fi
+
+ echo "${mech}: dce-style ${iov}" ; > messages.log
+ ${context} \
+ --mech-type=${mech} \
+ --anonymous --dce-style \
+ --wrapunwrap ${iov} \
+ --name-type=hostbased-service host@lucid.test.h5l.se || \
+ { eval "$testfailed"; }
+
+done
+
+trap "" EXIT
+
+exit $exitcode
diff --git a/third_party/heimdal/tests/gss/check-ntlm.in b/third_party/heimdal/tests/gss/check-ntlm.in
new file mode 100644
index 0000000..f953630
--- /dev/null
+++ b/third_party/heimdal/tests/gss/check-ntlm.in
@@ -0,0 +1,168 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+env_setup="@env_setup@"
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+../db/have-db || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+cache="FILE:krb5ccfile"
+cacheds="FILE:krb5ccfile-ds"
+
+kinit="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cache ${afs_no_afslog}"
+kinitds="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cacheds ${afs_no_afslog}"
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r $R"
+kdc="${TESTS_ENVIRONMENT} ../../kdc/kdc --addresses=localhost -P $port"
+kdigest="${TESTS_ENVIRONMENT} ../../kuser/kdigest"
+
+context="${TESTS_ENVIRONMENT} ../../lib/gssapi/test_context"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+KRB5CCNAME=${cache}
+KRB5_KTNAME="${keytab}"
+export KRB5_KTNAME
+KRB5CCNAME="${cache}"
+export KRB5CCNAME
+NTLM_ACCEPTOR_CCACHE="${cacheds}"
+export NTLM_ACCEPTOR_CCACHE
+NTLM_USER_FILE="${srcdir}/ntlm-user-file.txt"
+export NTLM_USER_FILE
+
+GSSAPI_SPNEGO_NAME=host@host.test.h5l.se
+export GSSAPI_SPNEGO_NAME
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p p1 --use-defaults host/host.test.h5l.se@${R} || exit 1
+${kadmin} ext -k ${keytab} host/host.test.h5l.se@${R} || exit 1
+
+${kadmin} add -p kaka --use-defaults digest/${R}@${R} || exit 1
+
+${kadmin} add -p ds --use-defaults digestserver@${R} || exit 1
+${kadmin} modify --attributes=+allow-digest digestserver@${R} || exit 1
+
+${kadmin} add -p u1 --use-defaults user1@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo u1 > ${objdir}/foopassword
+echo ds > ${objdir}/barpassword
+
+echo Starting kdc
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+exitcode=0
+
+echo "Getting client initial tickets"
+${kinit} --password-file=${objdir}/foopassword user1@${R} || exitcode=1
+echo "Getting digestserver initial tickets"
+${kinitds} --password-file=${objdir}/barpassword digestserver@${R} || exitcode=1
+
+echo "======probe"
+KRB5CCNAME="$cacheds"
+
+ ${kdigest} digest-probe --realm=${R} > /dev/null || \
+ { exitcode=1; echo "test failed"; }
+
+echo "======context building ntlm"
+
+NTLM_USER_FILE="${srcdir}/ntlm-user-file.txt-no"
+KRB5CCNAME="$cache"
+
+echo "no NTLM initiator creds"
+${context} --mech-type=ntlm \
+ --mutual \
+ --name-type=hostbased-service \
+ --ret-mech-type=ntlm \
+ host@host.test.h5l.se 2> /dev/null && \
+ { exitcode=1 ; echo "test failed"; }
+
+echo "Getting client initial tickets (with ntlm creds)"
+${kinit} --password-file=${objdir}/foopassword --ntlm-domain=TEST user1@${R} || exitcode=1
+
+echo "NTLM initiator krb5 creds"
+${context} --mech-type=ntlm \
+ --mutual \
+ --name-type=hostbased-service \
+ --ret-mech-type=ntlm \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo "test failed"; }
+
+echo "NTLM initiator krb5 creds (getverifymic, wrapunwrap)"
+${context} --mech-type=ntlm \
+ --mutual \
+ --name-type=hostbased-service \
+ --ret-mech-type=ntlm \
+ --getverifymic --wrapunwrap \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo "test failed"; }
+
+trap "" EXIT
+
+echo "killing kdc (${kdcpid})"
+kill ${kdcpid} 2> /dev/null
+
+exit $exitcode
+
+
diff --git a/third_party/heimdal/tests/gss/check-spnego.in b/third_party/heimdal/tests/gss/check-spnego.in
new file mode 100644
index 0000000..d6e4d83
--- /dev/null
+++ b/third_party/heimdal/tests/gss/check-spnego.in
@@ -0,0 +1,246 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+env_setup="@env_setup@"
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+../db/have-db || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+cache="FILE:krb5ccfile"
+cacheds="FILE:krb5ccfile-ds"
+
+kinit="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cache ${afs_no_afslog} --forwardable"
+kinitds="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cacheds ${afs_no_afslog}"
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r $R"
+kdc="${TESTS_ENVIRONMENT} ../../kdc/kdc --addresses=localhost -P $port"
+
+context="${TESTS_ENVIRONMENT} ../../lib/gssapi/test_context"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+KRB5CCNAME=${cache}
+KRB5_KTNAME="${keytab}"
+export KRB5_KTNAME
+KRB5CCNAME="${cache}"
+export KRB5CCNAME
+NTLM_ACCEPTOR_CCACHE="${cacheds}"
+export NTLM_ACCEPTOR_CCACHE
+NTLM_USER_FILE="${srcdir}/ntlm-user-file.txt"
+export NTLM_USER_FILE
+
+GSSAPI_SPNEGO_NAME=host@host.test.h5l.se
+export GSSAPI_SPNEGO_NAME
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p p1 --use-defaults host/host.test.h5l.se@${R} || exit 1
+${kadmin} ext -k ${keytab} host/host.test.h5l.se@${R} || exit 1
+
+${kadmin} add -p kaka --use-defaults digest/${R}@${R} || exit 1
+
+${kadmin} add -p ds --use-defaults digestserver@${R} || exit 1
+${kadmin} modify --attributes=+allow-digest digestserver@${R} || exit 1
+
+${kadmin} add -p u1 --use-defaults user1@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo u1 > ${objdir}/foopassword
+echo ds > ${objdir}/barpassword
+
+echo Starting kdc
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+exitcode=0
+
+echo "Getting client initial tickets"
+${kinit} --password-file=${objdir}/foopassword user1@${R} || exitcode=1
+echo "Getting digestserver initial tickets"
+${kinitds} --password-file=${objdir}/barpassword digestserver@${R} || exitcode=1
+
+echo "======context building for each mech"
+
+for mech in ntlm krb5 ; do
+ echo "${mech}"
+ ${context} --mech-type=${mech} --ret-mech-type=${mech} \
+ --client-ccache="${cache}" \
+ --gsskrb5-acceptor-identity="${keytab}" \
+ --name-type=hostbased-service host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+done
+
+echo "spnego"
+${context} \
+ --client-ccache="${cache}" \
+ --mech-type=spnego \
+ --ret-mech-type=krb5 \
+ --name-type=hostbased-service \
+ --export-import-context \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+
+echo "spnego (split tokens)"
+${context} \
+ --token-split=128 \
+ --client-ccache="${cache}" \
+ --mech-type=spnego \
+ --ret-mech-type=krb5 \
+ --name-type=hostbased-service \
+ --export-import-context \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+
+echo "test failure cases"
+${context} --mech-type=ntlm --ret-mech-type=krb5 \
+ --client-ccache="${cache}" \
+ --name-type=hostbased-service host@host.test.h5l.se 2> /dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+${context} --mech-type=krb5 --ret-mech-type=ntlm \
+ --client-ccache="${cache}" \
+ --name-type=hostbased-service host@host.test.h5l.se 2> /dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+echo "======spnego variants context building"
+
+for arg in \
+ "" \
+ "--mutual" \
+ "--delegate" \
+ "--mutual --delegate" \
+ "--getverifymic --wrapunwrap" \
+ "--mutual --getverifymic --wrapunwrap" \
+ ; do
+
+ echo "no NTLM acceptor cred ${arg}"
+ NTLM_ACCEPTOR_CCACHE="${cacheds}-no"
+ ${context} --mech-type=spnego \
+ $arg \
+ --name-type=hostbased-service \
+ --ret-mech-type=krb5 \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+ NTLM_ACCEPTOR_CCACHE="${cacheds}"
+
+ echo "no NTLM initiator cred ${arg}"
+ NTLM_USER_FILE="${srcdir}/ntlm-user-file.txt-no"
+ ${context} --mech-type=spnego \
+ $arg \
+ --name-type=hostbased-service \
+ --ret-mech-type=krb5 \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+ NTLM_USER_FILE="${srcdir}/ntlm-user-file.txt"
+
+ echo "no krb5 acceptor cred ${arg}"
+ KRB5_KTNAME="${keytab}-no"
+ ${context} --mech-type=spnego \
+ $arg \
+ --server-no-delegate \
+ --name-type=hostbased-service \
+ --ret-mech-type=ntlm \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+ KRB5_KTNAME="${keytab}"
+
+ echo "no explicit krb5 acceptor cred ${arg}"
+ ${context} --mech-type=spnego \
+ $arg \
+ --gsskrb5-acceptor-identity="${keytab}-no" \
+ --server-no-delegate \
+ --name-type=hostbased-service \
+ --ret-mech-type=krb5 \
+ host@host.test.h5l.se 2>/dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+ echo "no krb5 initiator cred ${arg}"
+ KRB5CCNAME="${cache}-no"
+ ${context} --mech-type=spnego \
+ $arg \
+ --server-no-delegate \
+ --name-type=hostbased-service \
+ --ret-mech-type=ntlm \
+ host@host.test.h5l.se || \
+ { exitcode=1 ; echo test failed; }
+ KRB5CCNAME="${cache}"
+
+ echo "no explicit krb5 initiator cred ${arg}"
+ ${context} --mech-type=spnego \
+ $arg \
+ --client-ccache="${cache}-no" \
+ --server-no-delegate \
+ --name-type=hostbased-service \
+ --ret-mech-type=krb5 \
+ host@host.test.h5l.se 2>/dev/null && \
+ { exitcode=1 ; echo test failed; }
+
+done
+
+trap "" EXIT
+
+echo "killing kdc (${kdcpid})"
+kill ${kdcpid} 2> /dev/null
+
+exit $exitcode
+
+
diff --git a/third_party/heimdal/tests/gss/include-krb5.conf b/third_party/heimdal/tests/gss/include-krb5.conf
new file mode 100644
index 0000000..ae21e9e
--- /dev/null
+++ b/third_party/heimdal/tests/gss/include-krb5.conf
@@ -0,0 +1,17 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE
+ no-addresses = TRUE
+ dns_canonicalize_hostname = false
+ dns_lookup_realm = false
+ name_canon_rules = as-is:realm=TEST.H5L.SE
+ name_canon_rules = qualify:domain=test.h5l.se
+
+[domain_realms]
+ .test.h5l.se = TEST.H5L.SE
+
+[kdc]
+ enable-digest = true
+ digests_allowed = ntlm-v2,ntlm-v1-session,ntlm-v1
+
+[kadmin]
+ save-password = true
diff --git a/third_party/heimdal/tests/gss/krb5.conf.in b/third_party/heimdal/tests/gss/krb5.conf.in
new file mode 100644
index 0000000..01c4c2e
--- /dev/null
+++ b/third_party/heimdal/tests/gss/krb5.conf.in
@@ -0,0 +1,54 @@
+include @srcdirabs@/include-krb5.conf
+
+[libdefaults]
+ default_keytab_name = @objdir@/server.keytab
+ enable-kx509 = yes
+ kx509_store = PEM-FILE:/tmp/cert_%{euid}.pem
+ default_realm = TEST.H5L.SE
+ kuserok = SYSTEM-K5LOGIN:@srcdir@/../kdc/k5login
+ kuserok = USER-K5LOGIN
+ kuserok = SIMPLE
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ auth_to_local_names = {
+ user1 = mapped_user1
+ }
+ }
+
+[kdc]
+ enable-digest = true
+ allow-anonymous = true
+ digests_allowed = chap-md5,digest-md5,ntlm-v1,ntlm-v1-session,ntlm-v2,ms-chap-v2
+ strict-nametypes = true
+ synthetic_clients = true
+ enable_gss_preauth = true
+ gss_mechanisms_allowed = sanon-x25519
+ enable-pkinit = true
+ pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ pkinit_pool = FILE:@srcdir@/../../lib/hx509/data/sub-ca.crt
+# pkinit_revoke = CRL:@srcdir@/../../lib/hx509/data/crl1.crl
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_allow_proxy_certificate = true
+
+ database = {
+ dbname = @objdir@/current-db
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ log_file = @objdir@/current.log
+ }
+
+[hdb]
+ db-dir = @objdir@
+ enable_virtual_hostbased_princs = true
+ virtual_hostbased_princ_mindots = 1
+ virtual_hostbased_princ_maxdots = 3
+ same_realm_aliases_are_soft = true
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+include @srcdirabs@/missing-krb5.conf
diff --git a/third_party/heimdal/tests/gss/mech.in b/third_party/heimdal/tests/gss/mech.in
new file mode 100644
index 0000000..4c4acc9
--- /dev/null
+++ b/third_party/heimdal/tests/gss/mech.in
@@ -0,0 +1,5 @@
+#
+# Test GSS-API mechglue configuration file.
+#
+test_negoex_1 2.25.1414534758 @objdir@/../../lib/gssapi/.libs/test_negoex_mech.so
+test_negoex_2 2.25.1175737388 @objdir@/../../lib/gssapi/.libs/test_negoex_mech.so
diff --git a/third_party/heimdal/tests/gss/new_clients_k5.conf.in b/third_party/heimdal/tests/gss/new_clients_k5.conf.in
new file mode 100644
index 0000000..41c9e21
--- /dev/null
+++ b/third_party/heimdal/tests/gss/new_clients_k5.conf.in
@@ -0,0 +1,5 @@
+include @objdirabs@/krb5.conf
+
+[libdefaults]
+ client_aware_channel_bindings = true
+ report_canonical_client_name = true
diff --git a/third_party/heimdal/tests/gss/ntlm-user-file.txt b/third_party/heimdal/tests/gss/ntlm-user-file.txt
new file mode 100644
index 0000000..cd2c654
--- /dev/null
+++ b/third_party/heimdal/tests/gss/ntlm-user-file.txt
@@ -0,0 +1,2 @@
+# $Id$
+TEST:user1:u1
diff --git a/third_party/heimdal/tests/java/KerberosInit.java b/third_party/heimdal/tests/java/KerberosInit.java
new file mode 100644
index 0000000..9442417
--- /dev/null
+++ b/third_party/heimdal/tests/java/KerberosInit.java
@@ -0,0 +1,95 @@
+/*
+ *
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+import javax.security.auth.login.*;
+import javax.security.auth.callback.*;
+
+public class KerberosInit {
+
+ private class TestCallBackHandler implements CallbackHandler {
+
+ public void handle(Callback[] callbacks)
+ throws UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ if (callbacks[i] instanceof TextOutputCallback) {
+ TextOutputCallback toc = (TextOutputCallback)callbacks[i];
+ System.out.println(toc.getMessage());
+ } else if (callbacks[i] instanceof NameCallback) {
+ NameCallback nc = (NameCallback)callbacks[i];
+ nc.setName("lha");
+ } else if (callbacks[i] instanceof PasswordCallback) {
+ PasswordCallback pc = (PasswordCallback)callbacks[i];
+ pc.setPassword("foo".toCharArray());
+ } else {
+ throw new
+ UnsupportedCallbackException(callbacks[i],
+ "Unrecognized Callback");
+ }
+ }
+ }
+ }
+ private TestCallBackHandler getHandler() {
+ return new TestCallBackHandler();
+ }
+
+ public static void main(String[] args) {
+
+ LoginContext lc = null;
+ try {
+ lc = new LoginContext("kinit", new KerberosInit().getHandler());
+ } catch (LoginException e) {
+ System.err.println("Cannot create LoginContext. " + e.getMessage());
+ e.printStackTrace();
+ System.exit(1);
+ } catch (SecurityException e) {
+ System.err.println("Cannot create LoginContext. " + e.getMessage());
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ try {
+ lc.login();
+ } catch (LoginException e) {
+ System.err.println("Authentication failed:" + e.getMessage());
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ System.out.println("lc.login ok");
+ System.exit(0);
+ }
+}
+
diff --git a/third_party/heimdal/tests/java/Makefile.am b/third_party/heimdal/tests/java/Makefile.am
new file mode 100644
index 0000000..acbe874
--- /dev/null
+++ b/third_party/heimdal/tests/java/Makefile.am
@@ -0,0 +1,46 @@
+# $Id: Makefile.am 20739 2007-05-31 16:53:21Z lha $
+
+include $(top_srcdir)/Makefile.am.common
+
+noinst_DATA = krb5.conf
+
+check_SCRIPTS = $(SCRIPT_TESTS)
+
+SCRIPT_TESTS = check-kinit
+
+TESTS = $(SCRIPT_TESTS)
+
+port = 49188
+
+do_subst = sed -e 's,[@]srcdir[@],$(srcdir),g' \
+ -e 's,[@]env_setup[@],$(top_builddir)/tests/bin/setup-env,g' \
+ -e 's,[@]port[@],$(port),g' \
+ -e 's,[@]objdir[@],$(top_builddir)/tests/java,g'
+
+LDADD = ../../lib/krb5/libkrb5.la $(LIB_roken)
+
+check-kinit: check-kinit.in Makefile
+ $(do_subst) < $(srcdir)/check-kinit.in > check-kinit.tmp
+ chmod +x check-kinit.tmp
+ mv check-kinit.tmp check-kinit
+
+krb5.conf: krb5.conf.in Makefile
+ $(do_subst) < $(srcdir)/krb5.conf.in > krb5.conf.tmp
+ mv krb5.conf.tmp krb5.conf
+
+CLEANFILES= \
+ $(TESTS) \
+ *.tmp \
+ *.class \
+ current-db* \
+ krb5.conf \
+ messages.log
+
+
+EXTRA_DIST = \
+ NTMakefile \
+ KerberosInit.java \
+ jaas.conf \
+ check-kinit.in \
+ have-java.sh \
+ krb5.conf.in
diff --git a/third_party/heimdal/tests/java/NTMakefile b/third_party/heimdal/tests/java/NTMakefile
new file mode 100644
index 0000000..5783739
--- /dev/null
+++ b/third_party/heimdal/tests/java/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=tests\java
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/tests/java/check-kinit.in b/third_party/heimdal/tests/java/check-kinit.in
new file mode 100644
index 0000000..8203344
--- /dev/null
+++ b/third_party/heimdal/tests/java/check-kinit.in
@@ -0,0 +1,147 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+srcdir="@srcdir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+port="@port@"
+
+. ${env_setup}
+
+# Disable test if: no data, no java, or socket wrapper
+../db/have-db || exit 77
+sh ${srcdir}/have-java.sh || exit 77
+[ X"$SOCKET_WRAPPER_DIR" != X ] && exit 77
+
+R=TEST.H5L.SE
+server=host/localhost
+keytabfile="${objdir}/server.keytab"
+keytab="FILE:${keytabfile}"
+cache="FILE:${objdir}/cache.krb5"
+
+kinit="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cache ${afs_no_afslog}"
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r $R"
+kdc="${TESTS_ENVIRONMENT} ../../kdc/kdc --addresses=127.0.0.1 -P $port"
+gssclient="${TESTS_ENVIRONMENT} ../../appl/test/gssapi_client"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+rm -f ${keytabfile} messages.log
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+echo "Compile"
+javac -d "${objdir}" "${srcdir}/KerberosInit.java" || \
+ { echo "Failed to compile java program: $?" ; exit 77; }
+
+echo "Compile"
+javac -d "${objdir}" "${srcdir}/../../appl/test/jgssapi_server.java" || \
+ { echo "Failed to compile java program: $?" ; exit 77; }
+
+> messages.log
+
+echo foo > ${objdir}/foopassword
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p foo --use-defaults lha@${R} || exit 1
+${kadmin} modify --attributes=+requires-pre-auth lha@${R} || exit 1
+${kadmin} add -p kaka --use-defaults ${server}@${R} || exit 1
+${kadmin} ext -k ${keytab} ${server}@${R} || exit 1
+
+echo Starting kdc
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+echo "Run init"
+java \
+ -Dsun.security.krb5.debug=true \
+ -Djava.security.krb5.conf="${objdir}"/krb5.conf \
+ -Djava.security.auth.login.config="${srcdir}/jaas.conf" \
+ KerberosInit > output.tmp 2>&1 || { cat output.tmp ; exit 1; }
+
+
+# Disabled because of:
+#
+# http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7077646
+# http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7077640
+#
+
+if false ; then
+
+ echo "start server"
+ java \
+ -Dsun.security.krb5.debug=true \
+ -Djava.security.krb5.conf="${objdir}"/krb5.conf \
+ -Djavax.security.auth.useSubjectCredsOnly=false \
+ -Djava.security.auth.login.config="${srcdir}/jaas.conf" \
+ jgssapi_server > output.tmp 2>&1 &
+ javapid=$!
+ sleep 5
+
+ trap "kill -9 ${kdcpid} ${javapid}; echo signal killing kdc java; exit 1;" EXIT
+
+ echo "Getting client initial tickets"; > messages.log
+ ${kinit} --password-file=${objdir}/foopassword lha@$R || \
+ { echo "kinit failed" ; exit 1; }
+
+ env KRB5CCNAME=${cache} \
+ ${gssclient} --port=4717 --service=host localhost || exit 1
+
+ sleep 5
+
+ kill ${javapid}
+
+ grep 'Exception in thread' output.tmp && exit 1
+fi
+
+echo "Done"
+
+echo "killing kdc (${kdcpid} ${javapid})"
+kill $kdcpid $javapid || exit 1
+
+trap "" EXIT
+
+exit 0
diff --git a/third_party/heimdal/tests/java/have-java.sh b/third_party/heimdal/tests/java/have-java.sh
new file mode 100644
index 0000000..84ac00e
--- /dev/null
+++ b/third_party/heimdal/tests/java/have-java.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+echo "Checking for java and javac"
+
+oldifs=$IFS
+IFS=:
+set -- $PATH
+IFS=$oldifs
+for i in $*; do
+ test -n "$i" || i="."
+ test -x $i/java && j=f
+ test -x $i/javac && k=c
+done
+
+test "$j$k" = fc || exit 1
+
+# GNU GCC Java doesn't support Kerberos
+if java -version 2>&1 | grep 'gij' > /dev/null ; then
+ exit 1
+fi
+
+echo "ok"
+
+exit 0
diff --git a/third_party/heimdal/tests/java/jaas.conf b/third_party/heimdal/tests/java/jaas.conf
new file mode 100644
index 0000000..00a9e02
--- /dev/null
+++ b/third_party/heimdal/tests/java/jaas.conf
@@ -0,0 +1,14 @@
+/* $Id$ */
+
+kinit {
+ com.sun.security.auth.module.Krb5LoginModule required;
+};
+
+com.sun.security.jgss.accept {
+ com.sun.security.auth.module.Krb5LoginModule required
+ useKeyTab=true
+ storeKey=true
+ keyTab="server.keytab"
+ principal="host/localhost"
+ isInitiator=false;
+};
diff --git a/third_party/heimdal/tests/java/krb5.conf.in b/third_party/heimdal/tests/java/krb5.conf.in
new file mode 100644
index 0000000..ca6b74f
--- /dev/null
+++ b/third_party/heimdal/tests/java/krb5.conf.in
@@ -0,0 +1,32 @@
+# $Id$
+
+[libdefaults]
+ default_realm = TEST.H5L.SE
+
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+
+[kdc]
+ database = {
+ dbname = @objdir@/current-db
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ log_file = @objdir@/current.log
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+# Have both default and non default salting for single DES encryptes,
+# this to check if the kdc return default salting.
+[kadmin]
+ default_keys = aes256-cts-hmac-sha1-96:pw-salt
+ default_keys = aes128-cts-hmac-sha1-96:pw-salt
+ default_keys = des3-cbc-sha1:pw-salt
diff --git a/third_party/heimdal/tests/kdc/Makefile.am b/third_party/heimdal/tests/kdc/Makefile.am
new file mode 100644
index 0000000..09f6953
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/Makefile.am
@@ -0,0 +1,443 @@
+include $(top_srcdir)/Makefile.am.common
+
+noinst_DATA = \
+ an2ln-db.txt \
+ kdc-tester4.json \
+ krb5.conf \
+ krb5-kcm.conf \
+ krb5-cccol.conf \
+ krb5-authz.conf \
+ krb5-authz2.conf \
+ krb5-canon.conf \
+ krb5-canon2.conf \
+ krb5-hdb-mitdb.conf \
+ krb5-weak.conf \
+ krb5-pkinit.conf \
+ krb5-bx509.conf \
+ krb5-httpkadmind.conf \
+ krb5-pkinit-win.conf \
+ krb5-master2.conf \
+ krb5-slave2.conf \
+ krb5-slave.conf
+
+check_SCRIPTS = $(SCRIPT_TESTS)
+
+SCRIPT_TESTS = \
+ check-authz \
+ check-canon \
+ check-cc \
+ check-delegation \
+ check-des \
+ check-digest \
+ check-fast \
+ check-kadmin \
+ check-hdb-mitdb \
+ check-kdc \
+ check-kdc-weak \
+ check-keys \
+ check-kpasswdd \
+ check-pkinit \
+ check-bx509 \
+ check-httpkadmind \
+ check-iprop \
+ check-referral \
+ check-tester \
+ check-uu
+
+TESTS = $(SCRIPT_TESTS)
+
+port = 49188
+admport = 49189
+admport2 = 49190
+pwport = 49191
+restport = 49192
+restport2 = 49193
+ipropport = 49194
+ipropport2 = 49195
+pkinit_ticket_max_life_from_cert = 0
+
+if HAVE_DLOPEN
+do_dlopen = -e 's,[@]DLOPEN[@],true,g'
+else
+do_dlopen = -e 's,[@]DLOPEN[@],false,g'
+endif
+
+do_subst = $(heim_verbose)sed $(do_dlopen) \
+ -e 's,[@]env_setup[@],$(top_builddir)/tests/bin/setup-env,g' \
+ -e 's,[@]top_srcdir[@],$(top_srcdir),g' \
+ -e 's,[@]srcdir[@],$(srcdir),g' \
+ -e 's,[@]port[@],$(port),g' \
+ -e 's,[@]admport[@],$(admport),g' \
+ -e 's,[@]admport2[@],$(admport2),g' \
+ -e 's,[@]bx509port[@],$(restport),g' \
+ -e 's,[@]restport[@],$(restport),g' \
+ -e 's,[@]restport2[@],$(restport2),g' \
+ -e 's,[@]pwport[@],$(pwport),g' \
+ -e 's,[@]ipropport[@],$(ipropport),g' \
+ -e 's,[@]ipropport2[@],$(ipropport2),g' \
+ -e 's,[@]objdir[@],$(top_builddir)/tests/kdc,g' \
+ -e 's,[@]top_builddir[@],$(top_builddir),g' \
+ -e 's,[@]db_type[@],$(db_type),g' \
+ -e 's,[@]max_life_from_cert[@],$(pkinit_ticket_max_life_from_cert),g' \
+ -e 's,[@]ENABLE_AFS_STRING_TO_KEY[@],$(ENABLE_AFS_STRING_TO_KEY),' \
+ -e 's,[@]ENABLE_AFS_STRING_TO_KEY[@],$(ENABLE_AFS_STRING_TO_KEY),' \
+ -e 's,[@]EGREP[@],$(EGREP),g' \
+ -e 's,[@]MITKRB5[@],$(MITKRB5),g'
+
+chmod = chmod
+
+LDADD = ../../lib/krb5/libkrb5.la $(LIB_roken)
+
+check-authz: check-authz.in Makefile krb5-authz.conf krb5-authz2.conf
+ $(do_subst) < $(srcdir)/check-authz.in > check-authz.tmp && \
+ $(chmod) +x check-authz.tmp && \
+ mv check-authz.tmp check-authz
+
+check-canon: check-canon.in Makefile krb5-canon.conf krb5-canon2.conf
+ $(do_subst) < $(srcdir)/check-canon.in > check-canon.tmp && \
+ $(chmod) +x check-canon.tmp && \
+ mv check-canon.tmp check-canon
+
+check-cc: check-cc.in Makefile
+ $(do_subst) < $(srcdir)/check-cc.in > check-cc.tmp && \
+ $(chmod) +x check-cc.tmp && \
+ mv check-cc.tmp check-cc
+
+check-delegation: check-delegation.in Makefile
+ $(do_subst) < $(srcdir)/check-delegation.in > check-delegation.tmp && \
+ $(chmod) +x check-delegation.tmp && \
+ mv check-delegation.tmp check-delegation
+
+check-des: check-des.in Makefile krb5.conf
+ $(do_subst) < $(srcdir)/check-des.in > check-des.tmp && \
+ $(chmod) +x check-des.tmp && \
+ mv check-des.tmp check-des
+
+check-hdb-mitdb: check-hdb-mitdb.in Makefile krb5-hdb-mitdb.conf
+ $(do_subst) < $(srcdir)/check-hdb-mitdb.in > check-hdb-mitdb.tmp && \
+ $(chmod) +x check-hdb-mitdb.tmp && \
+ mv check-hdb-mitdb.tmp check-hdb-mitdb
+
+check-fast: check-fast.in Makefile
+ $(do_subst) < $(srcdir)/check-fast.in > check-fast.tmp && \
+ $(chmod) +x check-fast.tmp && \
+ mv check-fast.tmp check-fast
+
+check-kdc: check-kdc.in Makefile
+ $(do_subst) < $(srcdir)/check-kdc.in > check-kdc.tmp && \
+ $(chmod) +x check-kdc.tmp && \
+ mv check-kdc.tmp check-kdc
+
+check-kdc-weak: check-kdc-weak.in Makefile
+ $(do_subst) < $(srcdir)/check-kdc-weak.in > check-kdc-weak.tmp && \
+ $(chmod) +x check-kdc-weak.tmp && \
+ mv check-kdc-weak.tmp check-kdc-weak
+
+check-tester: check-tester.in kdc-tester4.json Makefile
+ $(do_subst) < $(srcdir)/check-tester.in > check-tester.tmp && \
+ $(chmod) +x check-tester.tmp && \
+ mv check-tester.tmp check-tester
+
+check-keys: check-keys.in Makefile
+ $(do_subst) < $(srcdir)/check-keys.in > check-keys.tmp && \
+ $(chmod) +x check-keys.tmp && \
+ mv check-keys.tmp check-keys
+
+check-kinit: check-kinit.in Makefile
+ $(do_subst) < $(srcdir)/check-kinit.in > check-kinit.tmp && \
+ $(chmod) +x check-kinit.tmp && \
+ mv check-kinit.tmp check-kinit
+
+check-kadmin: check-kadmin.in Makefile
+ $(do_subst) < $(srcdir)/check-kadmin.in > check-kadmin.tmp && \
+ $(chmod) +x check-kadmin.tmp && \
+ mv check-kadmin.tmp check-kadmin
+
+check-uu: check-uu.in Makefile
+ $(do_subst) < $(srcdir)/check-uu.in > check-uu.tmp && \
+ $(chmod) +x check-uu.tmp && \
+ mv check-uu.tmp check-uu
+
+check-pkinit: check-pkinit.in Makefile krb5-pkinit.conf krb5-pkinit2.conf
+ $(do_subst) < $(srcdir)/check-pkinit.in > check-pkinit.tmp && \
+ $(chmod) +x check-pkinit.tmp && \
+ mv check-pkinit.tmp check-pkinit
+
+check-bx509: check-bx509.in Makefile krb5-bx509.conf
+ $(do_subst) < $(srcdir)/check-bx509.in > check-bx509.tmp && \
+ $(chmod) +x check-bx509.tmp && \
+ mv check-bx509.tmp check-bx509
+
+check-httpkadmind: check-httpkadmind.in Makefile krb5-httpkadmind.conf
+ $(do_subst) < $(srcdir)/check-httpkadmind.in > check-httpkadmind.tmp && \
+ $(chmod) +x check-httpkadmind.tmp && \
+ mv check-httpkadmind.tmp check-httpkadmind
+
+check-iprop: check-iprop.in Makefile krb5.conf krb5-master2.conf krb5-slave.conf krb5-slave2.conf
+ $(do_subst) < $(srcdir)/check-iprop.in > check-iprop.tmp && \
+ $(chmod) +x check-iprop.tmp && \
+ mv check-iprop.tmp check-iprop
+
+check-digest: check-digest.in Makefile
+ $(do_subst) < $(srcdir)/check-digest.in > check-digest.tmp && \
+ $(chmod) +x check-digest.tmp && \
+ mv check-digest.tmp check-digest
+
+check-referral: check-referral.in Makefile
+ $(do_subst) < $(srcdir)/check-referral.in > check-referral.tmp && \
+ $(chmod) +x check-referral.tmp && \
+ mv check-referral.tmp check-referral
+
+check-kpasswdd: check-kpasswdd.in Makefile
+ $(do_subst) < $(srcdir)/check-kpasswdd.in > check-kpasswdd.tmp && \
+ $(chmod) +x check-kpasswdd.tmp && \
+ mv check-kpasswdd.tmp check-kpasswdd
+
+kdc-tester4.json: kdc-tester4.json.in Makefile
+ $(do_subst) < $(srcdir)/kdc-tester4.json.in > kdc-tester4.json.tmp && \
+ mv kdc-tester4.json.tmp kdc-tester4.json
+
+krb5.conf: krb5.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],false,g' \
+ -e 's,[@]dk[@],,g' \
+ -e 's,[@]messages[@],messages,g' \
+ -e 's,[@]ipropstats[@],iprop-stats,g' \
+ -e 's,[@]signalsocket[@],signal,g' \
+ -e 's,[@]kdc[@],,g' < $(srcdir)/krb5.conf.in > krb5.conf.tmp && \
+ mv krb5.conf.tmp krb5.conf
+
+krb5-kcm.conf: krb5-kcm.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],false,g' \
+ -e 's,[@]dk[@],,g' \
+ -e 's,[@]kdc[@],,g' < $(srcdir)/krb5-kcm.conf.in > krb5-kcm.conf.tmp && \
+ mv krb5-kcm.conf.tmp krb5-kcm.conf
+
+krb5-cccol.conf: krb5-cccol.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],false,g' \
+ -e 's,[@]dk[@],,g' \
+ -e 's,[@]kdc[@],,g' < $(srcdir)/krb5-cccol.conf.in > krb5-cccol.conf.tmp && \
+ mv krb5-cccol.conf.tmp krb5-cccol.conf
+
+krb5-authz.conf: krb5-authz.conf.in Makefile
+ $(do_subst) < $(srcdir)/krb5-authz.conf.in > krb5-authz.conf.tmp && \
+ mv krb5-authz.conf.tmp krb5-authz.conf
+
+krb5-authz2.conf: krb5-authz2.conf.in Makefile
+ $(do_subst) < $(srcdir)/krb5-authz2.conf.in > krb5-authz2.conf.tmp && \
+ mv krb5-authz2.conf.tmp krb5-authz2.conf
+
+krb5-canon.conf: krb5-canon.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],false,g' \
+ -e 's,[@]dk[@],,g' \
+ -e 's,[@]kdc[@],,g' < $(srcdir)/krb5-canon.conf.in > krb5-canon.conf.tmp && \
+ mv krb5-canon.conf.tmp krb5-canon.conf
+
+krb5-canon2.conf: krb5-canon2.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],false,g' \
+ -e 's,[@]dk[@],,g' \
+ -e 's,[@]kdc[@],,g' < $(srcdir)/krb5-canon2.conf.in > krb5-canon2.conf.tmp && \
+ mv krb5-canon2.conf.tmp krb5-canon2.conf
+
+krb5-hdb-mitdb.conf: krb5-hdb-mitdb.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],false,g' \
+ -e 's,[@]dk[@],,g' \
+ -e 's,[@]kdc[@],,g' < $(srcdir)/krb5-hdb-mitdb.conf.in > krb5-hdb-mitdb.conf.tmp && \
+ mv krb5-hdb-mitdb.conf.tmp krb5-hdb-mitdb.conf
+
+krb5-weak.conf: krb5.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],true,g' \
+ -e 's,[@]dk[@],default_keys = aes256-cts-hmac-sha1-96:pw-salt arcfour-hmac-md5:pw-salt des3-cbc-sha1:pw-salt des:pw-salt,g' \
+ -e 's,[@]messages[@],messages,g' \
+ -e 's,[@]signalsocket[@],signal,g' \
+ -e 's,[@]ipropstats[@],iprop-stats,g' \
+ -e 's,[@]kdc[@],,g' < $(srcdir)/krb5.conf.in > krb5-weak.conf.tmp && \
+ mv krb5-weak.conf.tmp krb5-weak.conf
+
+krb5-slave.conf: krb5.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],true,g' \
+ -e 's,[@]dk[@],,g' \
+ -e 's,[@]messages[@],messages,g' \
+ -e 's,[@]signalsocket[@],signal2,g' \
+ -e 's,[@]ipropstats[@],iprop-stats,g' \
+ -e 's,[@]kdc[@],.slave,g' < $(srcdir)/krb5.conf.in > krb5-slave.conf.tmp && \
+ mv krb5-slave.conf.tmp krb5-slave.conf
+
+krb5-master2.conf: krb5.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],true,g' \
+ -e 's,[@]dk[@],,g' \
+ -e 's,[@]messages[@],messages2,g' \
+ -e 's,[@]signalsocket[@],signal2,g' \
+ -e 's,[@]ipropstats[@],iprop-stats2,g' \
+ -e 's,[@]kdc[@],.slave,g' < $(srcdir)/krb5.conf.in > krb5-master2.conf.tmp && \
+ mv krb5-master2.conf.tmp krb5-master2.conf
+
+krb5-slave2.conf: krb5.conf.in Makefile
+ $(do_subst) \
+ -e 's,[@]WEAK[@],true,g' \
+ -e 's,[@]dk[@],,g' \
+ -e 's,[@]messages[@],messages2,g' \
+ -e 's,[@]signalsocket[@],signal3,g' \
+ -e 's,[@]ipropstats[@],iprop-stats2,g' \
+ -e 's,[@]kdc[@],.slave2,g' < $(srcdir)/krb5.conf.in > krb5-slave2.conf.tmp && \
+ mv krb5-slave2.conf.tmp krb5-slave2.conf
+
+krb5-pkinit.conf: krb5-pkinit.conf.in Makefile
+ $(do_subst) -e 's,[@]w2k[@],no,g' < $(srcdir)/krb5-pkinit.conf.in > krb5-pkinit.conf.tmp && \
+ mv krb5-pkinit.conf.tmp krb5-pkinit.conf
+
+krb5-pkinit2.conf : pkinit_ticket_max_life_from_cert = 30d
+
+krb5-pkinit2.conf: krb5-pkinit.conf.in Makefile
+ $(do_subst) -e 's,[@]w2k[@],no,g' < $(srcdir)/krb5-pkinit.conf.in > krb5-pkinit2.conf.tmp && \
+ mv krb5-pkinit2.conf.tmp krb5-pkinit2.conf
+
+krb5-bx509.conf: krb5-bx509.conf.in Makefile
+ $(do_subst) -e 's,[@]w2k[@],no,g' < $(srcdir)/krb5-bx509.conf.in > krb5-bx509.conf.tmp && \
+ mv krb5-bx509.conf.tmp krb5-bx509.conf
+
+krb5-httpkadmind.conf: krb5-httpkadmind.conf.in Makefile
+ $(do_subst) -e 's,[@]w2k[@],no,g' < $(srcdir)/krb5-httpkadmind.conf.in > krb5-httpkadmind.conf.tmp && \
+ mv krb5-httpkadmind.conf.tmp krb5-httpkadmind.conf
+
+krb5-pkinit-win.conf: krb5-pkinit.conf.in Makefile
+ $(do_subst) -e 's,[@]w2k[@],yes,g' < $(srcdir)/krb5-pkinit.conf.in > krb5-pkinit-win.conf.tmp && \
+ mv krb5-pkinit-win.conf.tmp krb5-pkinit-win.conf
+
+clean: clean-am
+ rm -rf cc_dir authz_dir
+
+CLEANFILES= \
+ $(TESTS) \
+ *.crt \
+ *.der \
+ *.log \
+ *.pem \
+ *.pid \
+ *.tmp \
+ acache.krb5 \
+ barpassword \
+ ca.crt \
+ cache.krb5 \
+ cache2.krb5 \
+ cdigest-reply \
+ client-cache \
+ curlheaders \
+ current-db* \
+ current.log* \
+ digest-reply \
+ extracted_config \
+ extracted_keytab* \
+ foopassword \
+ foopassword.rkpty \
+ iprop-stats \
+ iprop-stats2 \
+ iprop.keytab \
+ ipropd.dumpfile \
+ kdc-tester4.json \
+ krb5-authz.conf \
+ krb5-authz2.conf \
+ krb5-canon.conf \
+ krb5-canon2.conf \
+ krb5-cc.conf \
+ krb5-cccol.conf \
+ krb5-hdb-mitdb.conf \
+ krb5-master2.conf \
+ krb5-pkinit-win.conf \
+ krb5-pkinit.conf \
+ krb5-pkinit2.conf \
+ krb5-bx509.conf \
+ krb5-httpkadmind.conf \
+ krb5-slave2.conf \
+ krb5-slave.conf \
+ krb5-weak.conf \
+ krb5.conf \
+ krb5.conf.keys \
+ kt \
+ leaks-log \
+ localname \
+ malloc-log \
+ malloc-log-master \
+ malloc-log-slave \
+ messages.log2 \
+ negotiate-token \
+ notfoopassword \
+ o2cache.krb5 \
+ o2digest-reply \
+ ocache.krb5 \
+ out-log \
+ req \
+ response-headers \
+ s2digest-reply \
+ sdb \
+ sdigest-init \
+ sdigest-reply \
+ server.keytab \
+ signal \
+ signal2 \
+ signal3 \
+ tempfile \
+ test-rc-file.rc \
+ ukt \
+ uuserver.log
+
+EXTRA_DIST = \
+ NTMakefile \
+ an2ln-db.txt \
+ check-authz.in \
+ check-bx509.in \
+ check-canon.in \
+ check-cc.in \
+ check-delegation.in \
+ check-des.in \
+ check-digest.in \
+ check-fast.in \
+ check-hdb-mitdb.in \
+ check-httpkadmind.in \
+ check-iprop.in \
+ check-kadmin.in \
+ check-kdc-weak.in \
+ check-kdc.in \
+ check-keys.in \
+ check-kinit.in \
+ check-kpasswdd.in \
+ check-pkinit.in \
+ check-referral.in \
+ check-tester.in \
+ check-uu.in \
+ donotexists.txt \
+ hdb-mitdb \
+ hdb-mitdb.kadm5 \
+ hdb-mitdb.mkey \
+ heimdal.acl \
+ iprop-acl \
+ k5login/foo \
+ k5login/mapped_user1 \
+ kdc-tester1.json \
+ kdc-tester2.json \
+ kdc-tester3.json \
+ kdc-tester4.json.in \
+ krb5-authz.conf.in \
+ krb5-authz2.conf.in \
+ krb5-bx509.conf.in \
+ krb5-canon.conf.in \
+ krb5-canon2.conf.in \
+ krb5-cccol.conf.in \
+ krb5-hdb-mitdb.conf.in \
+ krb5-httpkadmind.conf.in \
+ krb5-pkinit.conf.in \
+ krb5.conf.in \
+ krb5.conf.keys.in \
+ leaks-kill.sh \
+ ntlm-user-file.txt \
+ pki-mapping \
+ uuserver.txt \
+ wait-kdc.sh
diff --git a/third_party/heimdal/tests/kdc/NTMakefile b/third_party/heimdal/tests/kdc/NTMakefile
new file mode 100644
index 0000000..16ca0a7
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=tests\kdc
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/tests/kdc/an2ln-db.txt b/third_party/heimdal/tests/kdc/an2ln-db.txt
new file mode 100644
index 0000000..0b2fe38
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/an2ln-db.txt
@@ -0,0 +1,144 @@
+0575ee035f72dfb1 junk
+074897aaa3c4eace junk
+0c0015d1cb0edf2e junk
+15c02bb64902a207 junk
+1730cb4567c1bfce junk
+17c6e78171587710 junk
+21bef891f06af28e junk
+2358b67cdd649987 junk
+2b334ee5d32eb55b junk
+2f4cd4424e58822d junk
+4758f671c662b7e2 junk
+4bf0af25dd5211bd junk
+4d7f715b271ddb10 junk
+4f701fa5a4055c00 junk
+4f7634440d7bef3a junk
+5593a6bc03a68a3d junk
+5652948873ae4a9b junk
+5ababa9c833ce592 junk
+5c2fb83355b59cf1 junk
+5cf29f522abbcbe1 junk
+5d184a0f45bdaf61 junk
+70a01e2a09ba4b40 junk
+75bdfdb4c9c9b26b junk
+787aa58456e66463 junk
+788fa38b04026ca9 junk
+79ad9f69fb354592 junk
+7a686ba61c736eb1 junk
+807644c5c50f29d5 junk
+826de82aa81c3f8a junk
+85316d269114d787 junk
+86b7d20af35cffba junk
+895ca88e162d398f junk
+9008213d189aac2b junk
+98a51d5c9a172691 junk
+9af7d4a596944dcf junk
+a094067ad439189c junk
+a86904ae8f55df9e junk
+aa3ae6e252f65711 junk
+b19ffc6336a23be3 junk
+b4e37e4d23c4d7be junk
+b5c8b14d1e8ae7cb junk
+b9365f7ec3b0d52c junk
+bar/mapped1@TEST2.H5L.SE foobar
+bar/mapped2@TEST2.H5L.SE foobaz
+c118fb30610b8011 junk
+c19ffa62f50ad8f7 junk
+c9fce89738e25054 junk
+cb4555bb49891436 junk
+ccfb9930466fe627 junk
+cd2e8bc1fd014a86 junk
+d0d8dfeddf1b1eaa junk
+d22ff9ea01dfe15f junk
+d2bce251fcf6d5a3 junk
+d377b118646db95d junk
+d42fd3b12935a24a junk
+d948845a3b0068ac junk
+dbb143ecf6019b50 junk
+dbe41b5888e50c9c junk
+dd7a0a53ed569e21 junk
+dd82f76178ff0315 junk
+e1d62414205aa5a1 junk
+e3156ded04399027 junk
+e6bccd04c18fbd2e junk
+e9cb04e892e8f072 junk
+ebb5773344e4ade4 junk
+ef08d2dc9fef4f05 junk
+f59975170a04e071 junk
+f75338796ea735f0 junk
+f8cd2e85efa891af junk
+fd6e5e417b8296a7 junk
+foo/mapped1@TEST2.H5L.SE foo_mapped
+mapped1@TEST2.H5L.SE m1
+mapped1@TEST3.H5L.SE mapped1
+mapped2@TEST2.H5L.SE m2
+mapped2@TEST3.H5L.SE mapped2
+user1@@TEST.H5L.SE mapped_user1
+z008213d189aac2b junk
+z07644c5c50f29d5 junk
+z094067ad439189c junk
+z0a01e2a09ba4b40 junk
+z0d8dfeddf1b1eaa junk
+z118fb30610b8011 junk
+z19ffa62f50ad8f7 junk
+z19ffc6336a23be3 junk
+z1bef891f06af28e junk
+z1d62414205aa5a1 junk
+z22ff9ea01dfe15f junk
+z26de82aa81c3f8a junk
+z2bce251fcf6d5a3 junk
+z3156ded04399027 junk
+z358b67cdd649987 junk
+z377b118646db95d junk
+z42fd3b12935a24a junk
+z4e37e4d23c4d7be junk
+z5316d269114d787 junk
+z575ee035f72dfb1 junk
+z593a6bc03a68a3d junk
+z59975170a04e071 junk
+z5bdfdb4c9c9b26b junk
+z5c02bb64902a207 junk
+z5c8b14d1e8ae7cb junk
+z652948873ae4a9b junk
+z6b7d20af35cffba junk
+z6bccd04c18fbd2e junk
+z730cb4567c1bfce junk
+z74897aaa3c4eace junk
+z75338796ea735f0 junk
+z758f671c662b7e2 junk
+z7c6e78171587710 junk
+z86904ae8f55df9e junk
+z87aa58456e66463 junk
+z88fa38b04026ca9 junk
+z8a51d5c9a172691 junk
+z8cd2e85efa891af junk
+z9365f7ec3b0d52c junk
+z948845a3b0068ac junk
+z95ca88e162d398f junk
+z9ad9f69fb354592 junk
+z9cb04e892e8f072 junk
+z9fce89738e25054 junk
+za3ae6e252f65711 junk
+za686ba61c736eb1 junk
+zababa9c833ce592 junk
+zaf7d4a596944dcf junk
+zb334ee5d32eb55b junk
+zb4555bb49891436 junk
+zbb143ecf6019b50 junk
+zbb5773344e4ade4 junk
+zbe41b5888e50c9c junk
+zbf0af25dd5211bd junk
+zc0015d1cb0edf2e junk
+zc2fb83355b59cf1 junk
+zcf29f522abbcbe1 junk
+zcfb9930466fe627 junk
+zd184a0f45bdaf61 junk
+zd2e8bc1fd014a86 junk
+zd6e5e417b8296a7 junk
+zd7a0a53ed569e21 junk
+zd7f715b271ddb10 junk
+zd82f76178ff0315 junk
+zf08d2dc9fef4f05 junk
+zf4cd4424e58822d junk
+zf701fa5a4055c00 junk
+zf7634440d7bef3a junk
diff --git a/third_party/heimdal/tests/kdc/check-authz.in b/third_party/heimdal/tests/kdc/check-authz.in
new file mode 100644
index 0000000..02015b3
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-authz.in
@@ -0,0 +1,134 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="."
+
+. ${env_setup}
+
+srcdir="${top_srcdir}/tests/kdc"
+test_alname="${test_alname} --simple"
+
+rm -f localname
+
+check_localname() {
+ stderr=
+ if test "$2" -ne 0; then
+ stderr="2>/dev/null"
+ fi
+ eval ${test_alname} "'$1'" > localname $stderr
+ status=$?
+ if test $status -ne "$2"; then
+ echo "Unexpected exit code from test_alname $1: $status"
+ exit 1
+ fi
+ if test $status -ne 0; then
+ return 0
+ fi
+ read lname < localname
+ if test "X$lname" != "X$3"; then
+ echo "Unexpected mapping of $1: $lname"
+ exit 1
+ fi
+ return 0
+}
+
+R=TEST.H5L.SE
+R2=TEST2.H5L.SE
+R3=TEST3.H5L.SE
+R4=TEST4.H5L.SE
+
+KRB5_CONFIG="${objdir}/krb5-authz.conf"
+export KRB5_CONFIG
+
+echo "Checking 1-component principal names in default realms"
+check_localname mapped1@${R} 0 foo || exit 1
+check_localname mapped2@${R} 0 bar || exit 1
+check_localname mapped1@${R2} 0 m1 || exit 1
+check_localname mapped2@${R2} 0 m2 || exit 1
+check_localname mapped1@${R3} 0 mapped1 || exit 1
+check_localname mapped2@${R3} 0 mapped2 || exit 1
+check_localname notmapped1@${R} 0 notmapped1 || exit 1
+check_localname notmapped1@${R2} 0 notmapped1 || exit 1
+check_localname notmapped1@${R3} 0 notmapped1 || exit 1
+
+echo "Checking 1-component principal names in non-default realm"
+check_localname mapped1@${R4} 1 || exit 1
+check_localname notmapped1@${R4} 1 || exit 1
+
+echo "Checking 2-component principal names"
+check_localname foo/mapped1@${R} 0 foo || exit 1
+check_localname foo/mapped2@${R} 0 bar || exit 1
+check_localname bar/mapped1@${R2} 0 foobar || exit 1
+check_localname bar/mapped2@${R2} 0 foobaz || exit 1
+check_localname foo/mapped1@${R3} 1 || exit 1
+check_localname bar/mapped1@${R3} 1 || exit 1
+check_localname foo/notmapped1@${R} 1 || exit 1
+check_localname bar/notmapped1@${R2} 1 || exit 1
+
+echo "Checking 2-component principal names in non-default realm"
+check_localname foo/mapped1@${R4} 1 || exit 1
+check_localname bar/mapped1@${R4} 1 || exit 1
+check_localname foo/notmapped1@${R4} 1 || exit 1
+check_localname bar/notmapped1@${R4} 1 || exit 1
+
+echo "Checking for overflow"
+test_alname="${test_alname} --simple --lname-size=1"
+check_localname mapped1@${R} 3 || exit 1
+check_localname mapped2@${R} 3 || exit 1
+check_localname mapped1@${R2} 3 || exit 1
+check_localname mapped2@${R2} 3 || exit 1
+check_localname mapped1@${R3} 3 || exit 1
+check_localname mapped2@${R3} 3 || exit 1
+
+echo "Checking krb5_kuserok()"
+${test_kuserok} random-princ@RANDOM-REALM foo > /dev/null || exit 1
+${test_kuserok} mapped1@${R} foo > /dev/null || exit 1
+${test_kuserok} mapped1@${R2} m1 > /dev/null || exit 1
+${test_kuserok} notmapped1@${R3} notmapped1 > /dev/null || exit 1
+${test_kuserok} this-better-not-exist@NOR-THIS foo > /dev/null && exit 1
+
+KRB5_CONFIG="${objdir}/krb5-authz2.conf"
+export KRB5_CONFIG
+
+echo "Checking krb5_kuserok() (with authoritative k5login files)"
+${test_kuserok} random-princ@RANDOM-REALM foo > /dev/null || exit 1
+${test_kuserok} mapped1@${R} foo > /dev/null && exit 1
+${test_kuserok} mapped1@${R2} m1 > /dev/null || exit 1
+${test_kuserok} notmapped1@${R3} notmapped1 > /dev/null || exit 1
+${test_kuserok} this-better-not-exist@NOR-THIS foo > /dev/null && exit 1
+
+rm -f messages.log
+
+exit 0
diff --git a/third_party/heimdal/tests/kdc/check-bx509.in b/third_party/heimdal/tests/kdc/check-bx509.in
new file mode 100644
index 0000000..6d894ef
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-bx509.in
@@ -0,0 +1,1127 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+umask 077
+
+R=TEST.H5L.SE
+DCs="DC=test,DC=h5l,DC=se"
+
+port=@port@
+bx509port=@bx509port@
+
+server=datan.test.h5l.se
+otherserver=other.test.h5l.se
+
+kadmin="${kadmin} -l -r $R"
+bx509d="${bx509d} --allow-GET --reverse-proxied -p $bx509port -H $server --cert=${objdir}/bx509.pem -t"
+kdc="${kdc} --addresses=localhost -P $port"
+
+cachefile="${objdir}/cache.krb5"
+cache="FILE:${cachefile}"
+cachefile2="${objdir}/cache2.krb5"
+cache2="FILE:${cachefile2}"
+keyfile="${hx509_data}/key.der"
+keyfile2="${hx509_data}/key2.der"
+kt=${objdir}/kt
+keytab=FILE:${kt}
+ukt=${objdir}/ukt
+ukeytab=FILE:${ukt}
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist2="${klist} --hidden -v -c $cache2"
+klistjson="${klist} --json -c $cache"
+klist="${klist} --hidden -v -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+test_csr_authorizer="$test_csr_authorizer -A $objdir/authz_dir -S $objdir"
+kx509="${kx509} -c $cache"
+
+KRB5_CONFIG="${objdir}/krb5-bx509.conf"
+export KRB5_CONFIG
+
+HEIM_PIDFILE_DIR="${objdir}/"
+export HEIM_PIDFILE_DIR
+
+HEIM_IPC_DIR=$objdir
+export HEIM_IPC_DIR
+
+rsa=yes
+pkinit=no
+if ${hxtool} info | grep 'rsa: hx509 null RSA' > /dev/null ; then
+ rsa=no
+fi
+if ${hxtool} info | grep 'rand: not available' > /dev/null ; then
+ rsa=no
+fi
+
+if ${kinit} --help 2>&1 | grep "CA certificates" > /dev/null; then
+ pkinit=yes
+fi
+
+# If we doesn't support pkinit and have RSA, give up
+if test "$pkinit" != yes -o "$rsa" != yes ; then
+ exit 77
+fi
+
+
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+rm -f *.pem *.crt *.der
+rm -rf authz_dir
+
+mkdir -p authz_dir
+
+> messages.log
+
+kdcpid=
+bx509pid=
+test_csr_authorizer_pid=
+trap 'kill -9 ${kdcpid} ${bx509pid} ${test_csr_authorizer_pid}; echo signal killing kdc, bx509d, and test_csr_authorizer; exit 1;' EXIT
+
+# csr_grant ext-type value grantee_principal
+csr_grant() {
+ mkdir -p "${objdir}/authz_dir/${3}"
+ touch "${objdir}/authz_dir/${3}/${1}=${2}"
+}
+
+csr_revoke() {
+ rm -rf "${objdir}/authz_dir"
+ mkdir -p "${objdir}/authz_dir"
+}
+
+# get_cert "" curl-opts
+# get_cert "&qparams" curl-opts
+get_cert() {
+ url="http://${server}:${bx509port}/bx509?csr=$csr${1}"
+ shift
+ curl -g --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "$@" "$url"
+}
+
+get_with_token() {
+ if [ -n "$csr" ]; then
+ url="http://${server}:${bx509port}/${1}?csr=$csr${2}"
+ else
+ url="http://${server}:${bx509port}/${1}?${2}"
+ fi
+ shift 2
+
+ curl -fg --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -D response-headers \
+ "$@" "$url" &&
+ { echo "GET w/o CSRF token succeeded!"; exit 2; }
+ curl -g --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -D response-headers \
+ "$@" "$url"
+ grep ^X-CSRF-Token: response-headers >/dev/null ||
+ { echo "GET w/o CSRF token did not output a CSRF token!"; exit 2; }
+ curl -fg --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -H "$(sed -e 's/\r//' response-headers | grep ^X-CSRF-Token:)" \
+ "$@" "$url" ||
+ { echo "GET w/ CSRF failed"; exit 2; }
+}
+
+get_via_POST() {
+ endpoint=$1
+ shift
+
+ curl -fg --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -X POST -D response-headers \
+ "$@" "http://${server}:${bx509port}/${endpoint}" &&
+ { echo "POST w/o CSRF token succeeded!"; exit 2; }
+ curl -g --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -X POST -D response-headers \
+ "$@" "http://${server}:${bx509port}/${endpoint}"
+ grep ^X-CSRF-Token: response-headers >/dev/null ||
+ { echo "POST w/o CSRF token did not output a CSRF token!"; exit 2; }
+ curl -fg --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -H "$(sed -e 's/\r//' response-headers | grep ^X-CSRF-Token:)" \
+ -X POST \
+ "$@" "http://${server}:${bx509port}/${endpoint}" ||
+ { echo "POST w/ CSRF failed"; exit 2; }
+}
+
+rm -f $kt $ukt
+$ktutil -k $keytab add -r -V 1 -e aes128-cts-hmac-sha1-96 \
+ -p HTTP/datan.test.h5l.se@${R} ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+$ktutil -k $keytab list ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+$kimpersonate --ccache=$cache -k $keytab -R -t aes128-cts-hmac-sha1-96 \
+ -c foo@${R} -s HTTP/datan.test.h5l.se@${R} ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+$klist ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+
+echo "Setting up certificates"
+# We need:
+#
+# - a CA certificate for issuing client certificates
+# - a CA certificate for issuing server certificates
+# - a CA certificate for issuing mixed certificates
+# - a certificate for bx509 itself (well, not in reverse proxy mode, but we'll
+# make one anyways)
+
+# Make the realm's user cert issuer CA certificate.
+#
+# NOTE WELL: We need all three KeyUsage values listed below!
+# We also need this to be of type "pkinit-kdc",
+# which means we'll get an appropriate EKU OID as
+# well.
+$hxtool ca --issue-ca --self-signed --type=pkinit-kdc \
+ --ku=digitalSignature --ku=keyCertSign --ku=cRLSign \
+ --pk-init-principal=krbtgt/${R}@${R} \
+ --generate-key=rsa --key-bits=1024 \
+ --subject="OU=Users,CN=KDC,${DCs}" \
+ --certificate=PEM-FILE:"${objdir}/user-issuer.pem" ||
+ { echo "failed to setup CA certificate"; exit 2; }
+
+# We'll use the user cert issuer as the PKINIT anchor, allowing bx509-issued
+# certificates to be used for PKINIT. Though we won't be testing PKINIT here
+# -- we test kx509->PKINIT in check-pkinit.
+cp ${objdir}/user-issuer.pem ${objdir}/pkinit-anchor.pem
+
+# Put the cert alone in the trust anchors file
+ex "${objdir}/pkinit-anchor.pem" <<"EOF"
+/-----BEGIN CERTIFICATE-----
+1,.-1 d
+wq
+EOF
+
+$hxtool ca --issue-ca --self-signed \
+ --ku=digitalSignature --ku=keyCertSign --ku=cRLSign \
+ --generate-key=rsa --key-bits=1024 \
+ --subject="OU=Servers,CN=KDC,${DCs}" \
+ --certificate=PEM-FILE:"${objdir}/server-issuer.pem" ||
+ { echo "failed to setup CA certificate"; exit 2; }
+
+$hxtool ca --issue-ca --self-signed \
+ --ku=digitalSignature --ku=keyCertSign --ku=cRLSign \
+ --generate-key=rsa --key-bits=1024 \
+ --subject="OU=Users,CN=KDC,${DCs}" \
+ --certificate=PEM-FILE:"${objdir}/mixed-issuer.pem" ||
+ { echo "failed to setup CA certificate"; exit 2; }
+
+$hxtool ca --issue-ca --type=https-negotiate-server \
+ --ca-certificate=PEM-FILE:"${objdir}/server-issuer.pem" \
+ --ku=digitalSignature --pk-init-principal=HTTP/${server}@${R}\
+ --generate-key=rsa --key-bits=1024 --subject="" \
+ --certificate=PEM-FILE:"${objdir}/bx509.pem" ||
+ { echo "failed to setup CA certificate"; exit 2; }
+
+# XXX Before starting bx509d let us use kdc test programs to check that:
+#
+# - the negotiate token validator plugin works
+# - the authz_dir CSR authorizer plugin works
+# - the KDC CA tester program works
+
+echo "Check gss-token and Negotiate token validator plugin"
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server | tr A B)
+$test_token_validator -a datan.test.h5l.se Negotiate "$token" &&
+ { echo "Negotiate token validator accepted invalid token"; exit 2; }
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+$test_token_validator -a datan.test.h5l.se Negotiate "$token" ||
+ { echo "Negotiate token validator failed to validate valid token"; exit 2; }
+
+
+echo "Starting CSR authorizer IPC service"
+$test_csr_authorizer --server --daemon ||
+ { echo "Failed to start test_csr_authorizer service"; exit 2; }
+test_csr_authorizer_pid=`getpid test_csr_authorizer`
+
+# Make a CSR for foo@$R
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" --kerberos=foo@$R \
+ ${objdir}/req ||
+ { echo "Failed to make a CSR"; exit 2; }
+
+echo "Test CSR authorizer IPC service (deny foo@$R to san_pkinit=foo@$R)"
+csr_revoke
+$test_csr_authorizer PKCS10:${objdir}/req foo@$R &&
+ { echo "CSR authorizer IPC service granted foo@$R"; exit 2; }
+
+echo "Test CSR authorizer IPC service (grant foo@$R to san_pkinit=foo@$R)"
+csr_grant san_pkinit foo@$R foo@${R}
+$test_csr_authorizer PKCS10:${objdir}/req foo@$R ||
+ { echo "CSR authorizer IPC service rejected foo@$R"; exit 2; }
+
+# Make a CSR for bar@$R
+$hxtool request-create --subject='' --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" --kerberos=bar@$R \
+ ${objdir}/req ||
+ { echo "Failed to make a CSR"; exit 2; }
+
+echo "Test CSR authorizer IPC service (deny foo@$R to san_pkinit=bar@$R)"
+$test_csr_authorizer PKCS10:${objdir}/req foo@$R &&
+ { echo "CSR authorizer IPC service accepted foo@$R"; exit 2; }
+
+echo "Test CSR authorizer IPC service (grant foo@$R to san_pkinit=bar@$R)"
+csr_grant san_pkinit foo@$R bar@${R}
+$test_csr_authorizer PKCS10:${objdir}/req foo@$R &&
+ { echo "CSR authorizer IPC service accepted foo@$R"; exit 2; }
+
+# Make a CSR for foo@$R and bar@$R
+$hxtool request-create --subject='' --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" \
+ --kerberos=foo@$R --kerberos=bar@$R \
+ ${objdir}/req ||
+ { echo "Failed to make a CSR"; exit 2; }
+
+# Check that the authorizer does mark foo@$R as approved even though it denies
+# the overall request because it rejects bar@$R
+echo "Test CSR authorizer IPC service (partial authz)"
+csr_revoke
+csr_grant san_pkinit foo@$R foo@${R}
+# Check that the authorizer grants foo@$R
+$test_csr_authorizer PKCS10:${objdir}/req foo@$R san_pkinit=foo@$R ||
+ { echo "CSR authorizer IPC service partial approval check fail"; exit 2; }
+# Check that the authorizer rejects bar@$R
+$test_csr_authorizer PKCS10:${objdir}/req foo@$R san_pkinit=bar@$R &&
+ { echo "CSR authorizer IPC service partial approval check fail"; exit 2; }
+$test_csr_authorizer PKCS10:${objdir}/req foo@$R san_pkinit=foo@$R san_pkinit=bar@$R &&
+ { echo "CSR authorizer IPC service partial approval check fail"; exit 2; }
+
+echo "Making a plain CSR"
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" "${objdir}/req" ||
+ { echo "Failed to make a CSR"; exit 2; }
+
+rm -f trivial.pem server.pem email.pem
+
+echo "Testing plain user cert issuance KDC CA"
+$test_kdc_ca -a bx509 -A foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/trivial.pem ||
+ { echo "Trivial offline CA test failed"; exit 2; }
+$hxtool print --content PEM-FILE:${objdir}/trivial.pem ||
+ { echo "Trivial offline CA test failed"; exit 2; }
+$hxtool acert --end-entity \
+ --expr="%{certificate.subject} == \"CN=foo,$DCs\"" \
+ -P "foo@${R}" "FILE:${objdir}/trivial.pem" ||
+ { echo "Trivial offline CA test failed"; exit 2; }
+$hxtool acert --expr="%{certificate.subject} == \"OU=Users,CN=KDC,$DCs\"" \
+ --lacks-private-key "FILE:${objdir}/trivial.pem" ||
+ { echo "Trivial offline CA test failed (issuer private keys included!!)"; exit 2; }
+
+echo "Testing other cert issuance KDC CA"
+csr_revoke
+# https server cert
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" \
+ --eku=id_pkix_kp_serverAuth \
+ --dnsname=foo.test.h5l.se "${objdir}/req" ||
+ { echo "Failed to make a CSR with a dNSName SAN request"; exit 2; }
+$test_kdc_ca -a bx509 foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/server.pem &&
+ { echo "Trivial offline CA test failed: unauthorized issuance (dNSName)"; exit 2; }
+csr_grant san_dnsname foo.test.h5l.se foo@${R}
+csr_grant eku 1.3.6.1.5.5.7.3.1 foo@${R}
+$test_kdc_ca -a bx509 foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/server.pem ||
+ { echo "Offline CA test failed for explicitly authorized dNSName"; exit 2; }
+$hxtool print --content PEM-FILE:${objdir}/server.pem ||
+ { echo "Offline CA test failed for explicitly authorized dNSName"; exit 2; }
+$hxtool acert --expr="%{certificate.subject} == \"OU=Servers,CN=KDC,$DCs\"" \
+ --lacks-private-key "FILE:${objdir}/server.pem" ||
+ { echo "Trivial offline CA test failed (issuer private keys included!!)"; exit 2; }
+# email cert
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" \
+ --eku=id_pkix_kp_clientAuth \
+ --email=foo@test.h5l.se "${objdir}/req" ||
+ { echo "Failed to make a CSR with an rfc822Name SAN request"; exit 2; }
+$test_kdc_ca -a bx509 foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/email.pem &&
+ { echo "Offline CA test failed: unauthorized issuance (dNSName)"; exit 2; }
+csr_grant san_email foo@test.h5l.se foo@${R}
+csr_grant eku 1.3.6.1.5.5.7.3.2 foo@${R}
+$test_kdc_ca -a bx509 foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/email.pem ||
+ { echo "Offline CA test failed for explicitly authorized dNSName"; exit 2; }
+$hxtool print --content PEM-FILE:${objdir}/email.pem ||
+ { echo "Offline CA test failed for explicitly authorized dNSName"; exit 2; }
+$hxtool acert --expr="%{certificate.subject} == \"OU=Users,CN=KDC,$DCs\"" \
+ --lacks-private-key "FILE:${objdir}/email.pem" ||
+ { echo "Offline CA test failed (issuer private keys included!!)"; exit 2; }
+
+if ! which curl; then
+ echo "curl is not available -- not testing bx509d"
+ sh ${leaks_kill} test_csr_authorizer $test_csr_authorizer_pid || ec=1
+ trap '' EXIT
+ exit 77
+fi
+
+if ! test -x ${objdir}/../../kdc/bx509d; then
+ echo "Configured w/o libmicrohttpd -- not testing bx509d"
+ sh ${leaks_kill} test_csr_authorizer $test_csr_authorizer_pid || ec=1
+ trap '' EXIT
+ exit 77
+fi
+
+echo "Creating database"
+rm -f $kt $ukt
+${kadmin} <<EOF || exit 1
+init --realm-max-ticket-life=1day --realm-max-renewable-life=1month ${R}
+add -r --use-defaults foo@${R}
+add -r --use-defaults bar@${R}
+add -r --use-defaults baz@${R}
+add -r --use-defaults raz@${R}
+modify --pkinit-acl="CN=foo,DC=test,DC=h5l,DC=se" foo@${R}
+add -r --use-defaults HTTP/${server}@${R}
+ext_keytab -r -k $keytab HTTP/${server}@${R}
+add -r --use-defaults HTTP/${otherserver}@${R}
+ext_keytab -r -k $ukeytab foo@${R}
+EOF
+
+echo "Starting kdc";
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+${kdestroy}
+${kinit} -kt $ukeytab foo@${R} || exit 1
+$klist || { echo "failed to kinit"; exit 2; }
+
+
+echo "Starting bx509d"
+${bx509d} --daemon || { echo "bx509 failed to start"; exit 2; }
+bx509pid=`getpid bx509d`
+
+ec=0
+
+rm -f trivial.pem server.pem email.pem
+
+echo "Making a plain CSR (with BasicConstraints requesting CA cert)"
+csr_revoke
+$hxtool request-create --subject='CN=H5LCA' --generate-key=rsa --key-bits=1024 \
+ --ca --key=FILE:"${objdir}/k.der" "${objdir}/req" ||
+ { echo "Failed to make a CSR"; exit 2; }
+
+# XXX Add autoconf check for curl?
+# Create a barebones bx509 HTTP/1.1 client test program?
+
+echo "Fail to get a certificate using a CSR requesting a CA cert"
+# Encode the CSR in base64, then URL-encode it
+csr=$($rkbase64 -- ${objdir}/req | $rkvis -h --stdin)
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx; get_cert '' -sf -o "${objdir}/trivial.pem"); then
+ echo 'Issued a certificate for a CSR that requested a CA cert!'
+ exit 1
+else
+ echo 'CSRs requesting CA certs properly rejected'
+fi
+
+echo "Making a plain CSR (with BasicConstraints requesting EE cert)"
+csr_revoke
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --ee --key=FILE:"${objdir}/k.der" "${objdir}/req" ||
+ { echo "Failed to make a CSR"; exit 2; }
+
+echo "Fetching a trivial user certificate"
+# Encode the CSR in base64, then URL-encode it
+csr=$($rkbase64 -- ${objdir}/req | $rkvis -h --stdin)
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx; get_cert '' -sf -o "${objdir}/trivial.pem"); then
+ $hxtool print --content "FILE:${objdir}/trivial.pem"
+ if $hxtool acert --end-entity \
+ --expr="%{certificate.subject} == \"CN=foo,$DCs\"" \
+ -P "foo@${R}" "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate with a CSR w/ BasicConstraints requesting EE cert!'
+ else
+ echo 'FAIL: Obtained a trivial client certificate w/o expected PKINIT SAN)'
+ exit 1
+ fi
+ if $hxtool acert --expr="%{certificate.subject} == \"OU=Users,$DCs\"" \
+ --has-private-key "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ fi
+else
+ echo 'Failed to get a certificate with a CSR w/ BasicConstraints requesting EE cert!'
+ exit 1
+fi
+
+echo "Making a plain CSR"
+csr_revoke
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=FILE:"${objdir}/k.der" "${objdir}/req" ||
+ { echo "Failed to make a CSR"; exit 2; }
+
+echo "Fetching a trivial user certificate (no authentication, must fail)"
+# Encode the CSR in base64, then URL-encode it
+csr=$($rkbase64 -- ${objdir}/req | $rkvis -h --stdin)
+if (set -vx;
+ curl -g --resolve ${server}:${bx509port}:127.0.0.1 \
+ -sf -o "${objdir}/trivial.pem" \
+ "http://${server}:${bx509port}/bx509?csr=$csr"); then
+ $hxtool print --content "FILE:${objdir}/trivial.pem"
+ echo 'Got a certificate without authenticating!'
+ exit 1
+fi
+
+echo "Fetching a trivial user certificate"
+# Encode the CSR in base64, then URL-encode it
+csr=$($rkbase64 -- ${objdir}/req | $rkvis -h --stdin)
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx; get_cert '' -sf -o "${objdir}/trivial.pem"); then
+ $hxtool print --content "FILE:${objdir}/trivial.pem"
+ if $hxtool acert --end-entity \
+ --expr="%{certificate.subject} == \"CN=foo,$DCs\"" \
+ -P "foo@${R}" "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ else
+ echo 'FAIL: Obtained a trivial client certificate w/o expected PKINIT SAN)'
+ exit 1
+ fi
+ if $hxtool acert --expr="%{certificate.subject} == \"OU=Users,$DCs\"" \
+ --has-private-key "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ fi
+else
+ echo 'Failed to get a certificate!'
+ exit 1
+fi
+
+echo "Fetching a trivial user certificate (with POST, no auth, must fail)"
+# Encode the CSR in base64; curl will URL-encode it for us
+csr=$($rkbase64 -- ${objdir}/req)
+if (set -vx;
+ curl -fg --resolve ${server}:${bx509port}:127.0.0.1 \
+ -X POST -D response-headers \
+ -F csr="$csr" -o "${objdir}/trivial.pem" \
+ "http://${server}:${bx509port}/bx509" ); then
+ $hxtool print --content "FILE:${objdir}/trivial.pem"
+ echo 'Got a certificate without authenticating!'
+ exit 1
+fi
+
+echo "Fetching a trivial user certificate (with POST)"
+# Encode the CSR in base64; curl will URL-encode it for us
+csr=$($rkbase64 -- ${objdir}/req)
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx;
+ get_via_POST bx509 -F csr="$csr" -o "${objdir}/trivial.pem"); then
+ $hxtool print --content "FILE:${objdir}/trivial.pem"
+ if $hxtool acert --end-entity \
+ --expr="%{certificate.subject} == \"CN=foo,$DCs\"" \
+ -P "foo@${R}" "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ else
+ echo 'FAIL: Obtained a trivial client certificate w/o expected PKINIT SAN)'
+ exit 1
+ fi
+ if $hxtool acert --expr="%{certificate.subject} == \"OU=Users,$DCs\"" \
+ --has-private-key "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ fi
+else
+ echo 'Failed to get a certificate!'
+ exit 1
+fi
+
+echo "Checking that authorization is enforced"
+csr_revoke
+get_cert '&rfc822Name=foo@bar.example' -vvv -o "${objdir}/bad1.pem"
+if (set -vx; get_cert '&rfc822Name=foo@bar.example' -sf -o "${objdir}/trivial.pem"); then
+ $hxtool print --content "FILE:${objdir}/bad1.pem"
+ echo 'Obtained a client certificate for a non-granted name!'
+ exit 1
+else
+ echo 'Correctly failed to get a client certificate for a non-granted name'
+fi
+
+if (set -vx; get_cert "&dNSName=$server" -sf -o "${objdir}/bad2.pem"); then
+ $hxtool print --content "FILE:${objdir}/bad2.pem"
+ echo 'Obtained a server certificate for a non-granted name!'
+ exit 1
+else
+ echo 'Correctly failed to get a server certificate for a non-granted name'
+fi
+
+echo "Fetching a server certificate with one dNSName SAN"
+csr_grant san_dnsname $server foo@${R}
+if (set -vx; get_cert "&dNSName=$server" -sf -o "${objdir}/server.pem"); then
+ $hxtool print --content "FILE:${objdir}/server.pem"
+ if (set -vx; $hxtool acert --expr="%{certificate.subject} == \"\"" \
+ --end-entity -P foo@${R} \
+ "FILE:${objdir}/server.pem"); then
+ echo 'Got a broken server certificate (has PKINIT SAN)'
+ exit 1
+ elif $hxtool acert --end-entity -D $server "FILE:${objdir}/server.pem"; then
+ echo 'Successfully obtained a server certificate!'
+ else
+ echo 'Got a broken server certificate'
+ exit 1
+ fi
+else
+ echo 'Failed to get a server certificate!'
+ exit 1
+fi
+
+echo "Fetching a server certificate with two dNSName SANs"
+csr_grant san_dnsname "second-$server" foo@${R}
+if (set -vx;
+ get_cert "&dNSName=${server}&dNSName=second-$server" -sf \
+ -o "${objdir}/server2.pem"); then
+ $hxtool print --content "FILE:${objdir}/server2.pem"
+ if $hxtool acert --expr="%{certificate.subject} == \"\"" \
+ --end-entity -P foo@${R} \
+ "FILE:${objdir}/server2.pem"; then
+ echo 'Got a broken server certificate (has PKINIT SAN)'
+ exit 1
+ elif $hxtool acert --end-entity -D "$server" \
+ -D "second-$server" \
+ "FILE:${objdir}/server2.pem"; then
+ echo 'Successfully obtained a server certificate with two dNSName SANs!'
+ else
+ echo 'Got a broken server certificate (wanted two dNSName SANs)'
+ exit 1
+ fi
+else
+ echo 'Failed to get a server certificate with two dNSName SANs!'
+ exit 1
+fi
+
+echo "Fetching an email certificate"
+csr_grant san_email foo@bar.example foo@${R}
+if (set -vx; get_cert "&rfc822Name=foo@bar.example" -sf -o "${objdir}/email.pem"); then
+ $hxtool print --content "FILE:${objdir}/email.pem"
+ if $hxtool acert --end-entity -P "foo@${R}" "FILE:${objdir}/email.pem"; then
+ echo 'Got a broken email certificate (has PKINIT SAN)'
+ exit 1
+ elif $hxtool acert --expr="%{certificate.subject} == \"\"" \
+ --end-entity -M foo@bar.example \
+ "FILE:${objdir}/email.pem"; then
+ echo 'Successfully obtained a email certificate!'
+ else
+ echo 'Got a broken email certificate'
+ exit 1
+ fi
+else
+ echo 'Failed to get an email certificate!'
+ exit 1
+fi
+
+echo "Fetch TGT (not granted for other)"
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx;
+ curl -o "${cachefile2}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8"); then
+ echo "Got a TGT with /get-tgt end-point when not granted!"
+ exit 2
+fi
+
+echo "Fetch TGT"
+csr_grant san_pkinit foo@${R} foo@${R}
+csr_grant eku 1.3.6.1.5.2.3.4 foo@${R}
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile2}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?address=8.8.8.8"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+
+${klist2} | grep Addresses:.IPv4:8.8.8.8 ||
+ { echo "Failed to get a TGT with /get-tgt end-point with addresses"; exit 2; }
+
+echo "Fetch TGT (inception)"
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?address=8.8.8.8"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+${klist} | grep Addresses:.IPv4:8.8.8.8 ||
+ { echo "Failed to get a TGT with /get-tgt end-point with addresses"; exit 2; }
+
+echo "Fetch TGT (for other)"
+csr_grant san_pkinit bar@${R} foo@${R}
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+${klist} | grep Addresses:.IPv4:8.8.8.8 ||
+ { echo "Failed to get a TGT with /get-tgt end-point with addresses"; exit 2; }
+
+echo "Fetch TGT (for other, w/ lifetime req under max)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+csr_grant san_pkinit bar@${R} foo@${R}
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8&lifetime=3d"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+if which jq >/dev/null; then
+ if ! ${klistjson} | jq -e '
+ (reduce (.tickets[0]|(.Issued,.Expires)|
+ strptime("%b %e %H:%M:%S %Y")|mktime) as $t
+ (0; if .==0 then $t else $t - . end) / 86400) | floor |
+ . == 3'; then
+ echo "Incorrect lifetime"
+ exit 2
+ fi
+fi
+
+echo "Fetch TGT (for other, w/ lifetime req over max)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+csr_grant san_pkinit bar@${R} foo@${R}
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8&lifetime=10d"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+if which jq >/dev/null; then
+ if ! ${klistjson} | jq -e '
+ (.tickets[0].Issued | strptime("%b %e %H:%M:%S %Y")|mktime) as $iat
+ | (.tickets[0].Expires | strptime("%b %e %H:%M:%S %Y")|mktime) as $exp
+ | (($exp - $iat) / 86400) as $life_days
+ | ($life_days > 4 and $life_days <= 5)'; then
+ echo "Incorrect lifetime"
+ exit 2
+ fi
+fi
+
+echo "Fetch TGT (for other, w/ lifetime req under max)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+csr_grant san_pkinit bar@${R} foo@${R}
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -o "${cachefile}" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgt?cname=bar@${R}&address=8.8.8.8&address=8.9.10.11&address=11.11.11.11&address=12.12.12.12&lifetime=5d"); then
+ echo "Failed to get a TGT with /get-tgt end-point"
+ exit 2
+fi
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+if which jq >/dev/null; then
+ if ! ${klistjson} | jq -e '
+ (reduce (.tickets[0]|(.Issued,.Expires)|
+ strptime("%b %e %H:%M:%S %Y")|mktime) as $t
+ (0; if .==0 then $t else $t - . end) / 86400) |
+ . >= 4'; then
+ echo "Failed to get a TGT with /get-tgt end-point with addresses"
+ exit 2
+ fi
+fi
+
+echo "Fetch TGTs (batch, authz fail)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+csr_revoke
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+rm -f "${cachefile}.json"
+if (set -vx;
+ curl -o "${cachefile}.json" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgts?cname=bar@${R}&cname=baz@${R}"); then
+ # 200 Ok is not a problem. We have to check that the result is sane.
+ true
+else
+ if grep ccache "${cachefile}.json"; then
+ echo "Got TGTs with /get-tgts end-point that should have been denied"
+ exit 2;
+ fi
+ if ! grep error_code "${cachefile}.json" > /dev/null; then
+ cat "${cachefile}.json"
+ echo "Request failed w/o error information"
+ exit 2;
+ fi
+fi
+cat "${cachefile}.json"
+if grep ccache "${cachefile}.json"; then
+ echo "Got TGTs with /get-tgts end-point that should have been denied"
+ exit 2;
+fi
+
+echo "Fetch TGTs (batch, partial authz with IPC authorizer)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+csr_revoke
+csr_grant san_pkinit bar@${R} foo@${R}
+csr_grant san_pkinit baz@${R} foo@${R}
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -vvvo "${cachefile}.json" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgts?cname=bar@${R}&cname=raz@${R}&cname=baz@${R}"); then
+ echo "Failed to get TGTs batch including non-existent principal"
+ exit 2
+fi
+if which jq >/dev/null; then
+ set -vx
+ jq -e . "${cachefile}.json" > /dev/null ||
+ { echo "/get-tgts produced non-JSON"; exit 2; }
+ jq -es '.[]|select(.name|startswith("raz@"))|(.error_code//empty)' "${cachefile}.json" > /dev/null ||
+ { echo "No error was reported for raz@${R}!"; exit 2; }
+ jq -es '.[]|select(.name|startswith("raz@"))|(.ccache//"")|(length==0)' "${cachefile}.json" > /dev/null ||
+ { echo "Non-empty ccache included for raz@${R}!"; exit 2; }
+
+ # Check bar@$R's tickets:
+ jq -r 'select(.name|startswith("bar@")).ccache' "${cachefile}.json" |
+ $rkbase64 -d -- - > "${cachefile}"
+ ${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+ ${klistjson} | jq -e --arg p bar@$R '.principal == $p' > /dev/null ||
+ { echo "/get-tgts produced wrong TGTs"; exit 2; }
+
+ # Check baz@$R's tickets:
+ jq -r 'select(.name|startswith("baz@")).ccache' "${cachefile}.json" |
+ $rkbase64 -d -- - > "${cachefile}"
+ ${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+ ${klistjson} | jq -e --arg p baz@$R '.principal == $p' > /dev/null ||
+ { echo "/get-tgts produced wrong TGTs"; exit 2; }
+fi
+
+echo "Fetch TGTs (batch, partial authz)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+csr_revoke
+csr_grant san_pkinit bar@${R} foo@${R}
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -vvvo "${cachefile}.json" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgts?cname=not@${R}&cname=bar@${R}&cname=baz@${R}"); then
+ echo "Failed to get TGTs batch including non-existent principal"
+ exit 2
+fi
+if which jq >/dev/null; then
+ set -vx
+ jq -e . "${cachefile}.json" > /dev/null ||
+ { echo "/get-tgts produced non-JSON"; exit 2; }
+ jq -es '.[]|select(.name|startswith("not@"))|(.error_code//empty)' "${cachefile}.json" > /dev/null ||
+ { echo "No error was reported for not@${R}!"; exit 2; }
+ jq -es '.[]|select(.name|startswith("not@"))|(.ccache//"")|(length==0)' "${cachefile}.json" > /dev/null ||
+ { echo "Non-empty ccache included for not@${R}!"; exit 2; }
+ jq -es '.[]|select(.name|startswith("baz@"))|(.error_code//empty)' "${cachefile}.json" > /dev/null ||
+ { echo "No error was reported for baz@${R}!"; exit 2; }
+ jq -es '.[]|select(.name|startswith("baz@"))|(.ccache//"")|(length==0)' "${cachefile}.json" > /dev/null ||
+ { echo "Non-empty ccache included for baz@${R}!"; exit 2; }
+
+ # Check bar@$R's tickets:
+ jq -r 'select(.name|startswith("bar@")).ccache' "${cachefile}.json" |
+ $rkbase64 -d -- - > "${cachefile}"
+ ${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+ ${klistjson} | jq -e --arg p bar@$R '.principal == $p' > /dev/null ||
+ { echo "/get-tgts produced wrong TGTs"; exit 2; }
+fi
+
+echo "Fetch TGTs (batch, authz pass)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+csr_grant san_pkinit bar@${R} foo@${R}
+csr_grant san_pkinit baz@${R} foo@${R}
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -vvvo "${cachefile}.json" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgts?cname=bar@${R}&cname=baz@${R}"); then
+ echo "Failed to get TGTs batch"
+ exit 2
+fi
+if which jq >/dev/null; then
+ jq -e . "${cachefile}.json" > /dev/null ||
+ { echo "/get-tgts produced non-JSON"; exit 2; }
+
+ # Check bar@$R's tickets:
+ jq -r 'select(.name|startswith("bar@")).ccache' "${cachefile}.json" |
+ $rkbase64 -d -- - > "${cachefile}"
+ ${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+ ${klistjson} | jq -e --arg p bar@$R '.principal == $p' > /dev/null ||
+ { echo "/get-tgts produced wrong TGTs"; exit 2; }
+
+ # Check baz@$R's tickets:
+ jq -r 'select(.name|startswith("baz@")).ccache' "${cachefile}.json" |
+ $rkbase64 -d -- - > "${cachefile}"
+ ${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+ ${klistjson} | jq -e --arg p baz@$R '.principal == $p' > /dev/null ||
+ { echo "/get-tgts produced wrong TGTs"; exit 2; }
+fi
+
+echo "Fetch TGTs (batch, authz pass, one non-existent principal)"
+${kadmin} modify --max-ticket-life=10d krbtgt/${R}@${R}
+csr_grant san_pkinit bar@${R} foo@${R}
+csr_grant san_pkinit baz@${R} foo@${R}
+csr_grant san_pkinit not@${R} foo@${R}
+${kdestroy}
+token=$(KRB5CCNAME=$cache2 $gsstoken HTTP@$server)
+if ! (set -vx;
+ curl -vvvo "${cachefile}.json" -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/get-tgts?cname=not@${R}&cname=bar@${R}&cname=baz@${R}"); then
+ echo "Failed to get TGTs batch including non-existent principal"
+ exit 2
+fi
+if which jq >/dev/null; then
+ set -vx
+ jq -e . "${cachefile}.json" > /dev/null ||
+ { echo "/get-tgts produced non-JSON"; exit 2; }
+ jq -es '.[]|select(.name|startswith("not@"))|(.error_code//empty)' "${cachefile}.json" > /dev/null ||
+ { echo "No error was reported for not@${R}!"; exit 2; }
+
+ # Check bar@$R's tickets:
+ jq -r 'select(.name|startswith("bar@")).ccache' "${cachefile}.json" |
+ $rkbase64 -d -- - > "${cachefile}"
+ ${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+ ${klistjson} | jq -e --arg p bar@$R '.principal == $p' > /dev/null ||
+ { echo "/get-tgts produced wrong TGTs"; exit 2; }
+
+ # Check baz@$R's tickets:
+ jq -r 'select(.name|startswith("baz@")).ccache' "${cachefile}.json" |
+ $rkbase64 -d -- - > "${cachefile}"
+ ${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Fetched TGT didn't work"; exit 2; }
+ ${klistjson} | jq -e --arg p baz@$R '.principal == $p' > /dev/null ||
+ { echo "/get-tgts produced wrong TGTs"; exit 2; }
+fi
+
+echo "killing bx509d (${bx509pid})"
+sh ${leaks_kill} bx509d $bx509pid || ec=1
+
+echo "Starting bx509d (csrf-protection-type=GET-with-token, POST-with-header)"
+${bx509d} --csrf-protection-type=GET-with-token \
+ --csrf-protection-type=POST-with-header --daemon || {
+ echo "bx509 failed to start"
+ exit 2
+}
+bx509pid=`getpid bx509d`
+
+${kinit} -kt $ukeytab foo@${R} || exit 1
+$klist || { echo "failed to kinit"; exit 2; }
+
+echo "Fetching a trivial user certificate (GET with CSRF token)"
+csr=$($rkbase64 -- ${objdir}/req | $rkvis -h --stdin)
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx; get_with_token get-cert '' -o "${objdir}/trivial.pem"); then
+ $hxtool print --content "FILE:${objdir}/trivial.pem"
+ if $hxtool acert --end-entity \
+ --expr="%{certificate.subject} == \"CN=foo,$DCs\"" \
+ -P "foo@${R}" "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ else
+ echo 'FAIL: Obtained a trivial client certificate w/o expected PKINIT SAN)'
+ exit 1
+ fi
+ if $hxtool acert --expr="%{certificate.subject} == \"OU=Users,$DCs\"" \
+ --has-private-key "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ fi
+else
+ echo 'Failed to get a certificate!'
+ exit 1
+fi
+
+echo "Fetching a trivial user certificate (POST with X-CSRF header, no token)"
+# Encode the CSR in base64, then URL-encode it
+csr=$($rkbase64 -- ${objdir}/req | $rkvis -h --stdin)
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+if (set -vx; get_cert '' -H 'X-CSRF: junk' -X POST -sf -o "${objdir}/trivial.pem"); then
+ $hxtool print --content "FILE:${objdir}/trivial.pem"
+ if $hxtool acert --end-entity \
+ --expr="%{certificate.subject} == \"CN=foo,$DCs\"" \
+ -P "foo@${R}" "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ else
+ echo 'FAIL: Obtained a trivial client certificate w/o expected PKINIT SAN)'
+ exit 1
+ fi
+ if $hxtool acert --expr="%{certificate.subject} == \"OU=Users,$DCs\"" \
+ --has-private-key "FILE:${objdir}/trivial.pem"; then
+ echo 'Successfully obtained a trivial client certificate!'
+ fi
+else
+ echo 'Failed to get a certificate!'
+ exit 1
+fi
+
+echo "Fetch negotiate token (pre-test)"
+# Do what /bnegotiate does, roughly, prior to testing /bnegotiate
+$hxtool request-create --subject='' --generate-key=rsa --key-bits=1024 \
+ --key=PEM-FILE:"${objdir}/k.pem" "${objdir}/req" ||
+ { echo "Failed to make a CSR"; exit 2; }
+$test_kdc_ca -a bx509 -A foo@${R} PKCS10:${objdir}/req \
+ PEM-FILE:${objdir}/pkinit-test.pem ||
+ { echo "Trivial offline CA test failed (CA)"; exit 2; }
+cat ${objdir}/k.pem >> ${objdir}/pkinit-test.pem
+${kinit} -C PEM-FILE:${objdir}/pkinit-test.pem foo@${R} ||
+ { echo "Trivial offline CA test failed (PKINIT)"; exit 2; }
+${kgetcred} -H HTTP/${server}@${R} ||
+ { echo "Trivial offline CA test failed (TGS)"; exit 2; }
+KRB5CCNAME=$cache $gsstoken HTTP@$server | KRB5_KTNAME="$keytab" $gsstoken -r ||
+ { echo "Trivial offline CA test failed (gss-token)"; exit 2; }
+
+# Check that we get up to three tixaddrs k/v in the log
+grep 'REQ.*wrongaddr=true' ${objdir}/messages.log |
+ grep 'tixaddrs=IPv4:11.11.11.11' ||
+ { echo "KDC not warning about requests from wrong address"; exit 2; }
+
+echo "Fetching a Negotiate token"
+token=$(KRB5CCNAME=$cache $gsstoken HTTP@$server)
+csr=
+if (set -vx;
+ get_with_token get-negotiate-token "target=HTTP%40${server}" -o "${objdir}/negotiate-token"); then
+ # bx509 sends us a token w/o a newline for now; we add one because
+ # gss-token expects it.
+ test -s negotiate-token && echo >> negotiate-token
+ if test -s negotiate-token && KRB5_KTNAME="$keytab" $gsstoken -Nr < negotiate-token; then
+ echo 'Successfully obtained a Negotiate token!'
+ else
+ echo 'Failed to get a Negotiate token (got an unacceptable token)!'
+ exit 1
+ fi
+else
+ echo 'Failed to get a Negotiate token!'
+ exit 1
+fi
+
+referer=https://${otherserver}/blah
+redirect=$(${rkvis} -h https://${otherserver}/blah?q=whatever)
+if (set -vx;
+ curl -o negotiate-token -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/bnegotiate?target=HTTP%40${server}&redirect=${redirect}"); then
+ echo "Error: /bnegotiate with target and redirect succeeded"
+ exit 1
+fi
+
+if (set -vx;
+ curl -o negotiate-token -Lgsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ "http://${server}:${bx509port}/bnegotiate?redirect=${redirect}"); then
+ echo "Error: /bnegotiate with redirect but no Referer succeeded"
+ exit 1
+fi
+
+referer=http://${otherserver}/blah
+redirect=$(${rkvis} -h http://${otherserver}/blah?q=whatever)
+if (set -vx;
+ curl -gsf \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -H "Referer: $referer" \
+ "http://${server}:${bx509port}/bnegotiate?redirect=${redirect}"); then
+ echo "Error: redirect for non-https referer"
+ exit 1
+fi
+
+referer=https://${otherserver}/blah
+redirect=$(${rkvis} -h https://${otherserver}/blah?q=whatever)
+if (set -vx;
+ curl -gfs -D curlheaders \
+ --resolve ${server}:${bx509port}:127.0.0.1 \
+ -H "Authorization: Negotiate $token" \
+ -H "Referer: $referer" \
+ "http://${server}:${bx509port}/bnegotiate?redirect=${redirect}"); then
+ read junk code junk < curlheaders
+ if test "$code" = 307; then
+ echo "Got a proper redirect"
+ else
+ echo "Error: unexpected status code $code (wanted 307)"
+ fi
+else
+ echo "Error: no redirect"
+ exit 1
+fi
+
+echo "killing kdc (${kdcpid}) and bx509d (${bx509pid}) and test_csr_authorizer (${test_csr_authorizer_pid})"
+sh ${leaks_kill} kdc $kdcpid || ec=1
+sh ${leaks_kill} bx509d $bx509pid || ec=1
+sh ${leaks_kill} test_csr_authorizer $test_csr_authorizer_pid || ec=1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-canon.in b/third_party/heimdal/tests/kdc/check-canon.in
new file mode 100644
index 0000000..18b83a9
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-canon.in
@@ -0,0 +1,210 @@
+#!/bin/sh
+#
+# Copyright (c) 2011, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+# (krb5_kt_get_entry() is tested in another test)
+${have_db} || exit 77
+
+R1=TEST.H5L.SE
+R2=TEST2.H5L.SE
+R3=TEST3.H5L.SE
+
+port=@port@
+
+kadmin="${kadmin} -l -r ${R1}"
+kdc="${kdc} --addresses=localhost -P $port"
+
+cache="FILE:${objdir}/cache.krb5"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist="${klist} -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+
+KRB5_CONFIG="${objdir}/krb5-canon.conf"
+export KRB5_CONFIG
+
+testfailed="echo test failed; ${klist}; exit 1"
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo "Creating database"
+initflags="init --realm-max-ticket-life=1day --realm-max-renewable-life=1month"
+
+${kadmin} ${initflags} ${R1} || exit 1
+${kadmin} ${initflags} ${R2} || exit 1
+${kadmin} ${initflags} ${R3} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${R1} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R1}@${R2} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R2}@${R1} || exit 1
+${kadmin} add -p cross3 --use-defaults krbtgt/${R3}@${R1} || exit 1
+${kadmin} add -p cross4 --use-defaults krbtgt/${R1}@${R3} || exit 1
+${kadmin} add -p cross5 --use-defaults krbtgt/${R3}@${R2} || exit 1
+${kadmin} add -p cross6 --use-defaults krbtgt/${R2}@${R3} || exit 1
+
+${kadmin} add -p foo --use-defaults host/t1@${R1} || exit 1
+${kadmin} add -p foo --use-defaults host/t2@${R2} || exit 1
+${kadmin} add -p foo --use-defaults host/t3@${R3} || exit 1
+${kadmin} add -p foo --use-defaults host/t11.test1.h5l.se@${R1} || exit 1
+${kadmin} add -p foo --use-defaults host/t12.test1.h5l.se@${R2} || exit 1
+${kadmin} add -p foo --use-defaults host/t22.test2.h5l.se@${R2} || exit 1
+${kadmin} add -p foo --use-defaults host/t23.test2.h5l.se@${R3} || exit 1
+${kadmin} add -p foo --use-defaults host/t33.test3.h5l.se@${R3} || exit 1
+
+
+echo "Doing database check"
+${kadmin} check ${R1} || exit 1
+${kadmin} check ${R2} || exit 1
+${kadmin} check ${R3} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo "Starting kdc" ; > messages.log
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+ec=0
+
+echo "Getting client initial tickets";
+${kinit} --password-file=${objdir}/foopassword foo@${R1} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "get service tickets (success)"
+for host in t1 t2 t3 t11 t12 t22 t33 ; do
+ echo " $host"
+ ${kgetcred} --name-type=SRV_HST host $host || { ec=1 ; eval "${testfailed}"; }
+done
+echo "get service tickets (failure)"
+for host in t23 ; do
+ echo " $host"
+ ${kgetcred} --name-type=SRV_HST host $host 2>/dev/null && { ec=1 ; eval "${testfailed}"; }
+done
+
+echo "check result"
+${klist} | grep 'host/t1@$' > /dev/null ||
+ { ec=1 ; echo "t1 referral entry not present"; eval "${testfailed}"; }
+${klist} | grep "host/t1@${R1}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t1 entry not present"; eval "${testfailed}"; }
+${klist} | grep 'host/t2@$' > /dev/null ||
+ { ec=1 ; echo "t2 referral entry not present"; eval "${testfailed}"; }
+${klist} | grep "host/t2@${R2}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t2 entry not present"; eval "${testfailed}"; }
+${klist} | grep 'host/t3@$' > /dev/null ||
+ { ec=1 ; echo "t3 referral entry not present"; eval "${testfailed}"; }
+${klist} | grep "host/t3@${R3}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t3 entry not present"; eval "${testfailed}"; }
+${klist} | grep 'host/t11@$' > /dev/null ||
+ { ec=1 ; echo "t11 referral entry not present"; eval "${testfailed}"; }
+${klist} | grep "host/t11.test1.h5l.se@${R1}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t11 entry not present"; eval "${testfailed}"; }
+${klist} | grep 'host/t12@$' > /dev/null ||
+ { ec=1 ; echo "t12 referral entry not present"; eval "${testfailed}"; }
+${klist} | grep "host/t12.test1.h5l.se@${R2}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t12 entry not present"; eval "${testfailed}"; }
+${klist} | grep 'host/t22@$' > /dev/null ||
+ { ec=1 ; echo "t22 referral entry not present"; eval "${testfailed}"; }
+${klist} | grep "host/t22.test2.h5l.se@${R2}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t22 entry not present"; eval "${testfailed}"; }
+${klist} | grep 'host/t33@$' > /dev/null ||
+ { ec=1 ; echo "t33 referral entry not present"; eval "${testfailed}"; }
+${klist} | grep "host/t33.test3.h5l.se@${R3}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t33 entry not present"; eval "${testfailed}"; }
+
+
+${kdestroy}
+
+if false; then
+
+ # This may not be portable. It'd be nice to be able to set more of the
+ # resolver configuration via the environment!
+ LOCALDOMAIN=test1.h5l.se
+ export LOCALDOMAIN
+ KRB5_CONFIG="${objdir}/krb5-canon2.conf"
+ export KRB5_CONFIG
+
+ echo "Getting client initial tickets (round 2)";
+ ${kinit} --password-file=${objdir}/foopassword foo@${R1} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+ echo "get service tickets (success)"
+ for host in t1 t2 t3 t11 ; do
+ echo " $host"
+ ${kgetcred} --name-type=SRV_HST host $host || { ec=1 ; eval "${testfailed}"; }
+ done
+ echo "get service tickets (failure)"
+ for host in t12 t22 t23 t33 ; do
+ echo " $host"
+ ${kgetcred} --name-type=SRV_HST host $host 2> /dev/null &&
+ { ec=1 ; eval "${testfailed}"; }
+ done
+
+ echo "check result"
+ ${klist} | grep 'host/t1@$' > /dev/null ||
+ { ec=1 ; echo "t1 referral entry not present"; eval "${testfailed}"; }
+ ${klist} | grep "host/t1@${R1}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t1 entry not present"; eval "${testfailed}"; }
+ ${klist} | grep 'host/t2@$' > /dev/null ||
+ { ec=1 ; echo "t2 referral entry not present"; eval "${testfailed}"; }
+ ${klist} | grep "host/t2@${R2}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t2 entry not present"; eval "${testfailed}"; }
+ ${klist} | grep 'host/t3@$' > /dev/null ||
+ { ec=1 ; echo "t3 referral entry not present"; eval "${testfailed}"; }
+ ${klist} | grep "host/t3@${R3}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t3 entry not present"; eval "${testfailed}"; }
+ ${klist} | grep 'host/t11@$' > /dev/null ||
+ { ec=1 ; echo "t11 referral entry not present"; eval "${testfailed}"; }
+ ${klist} | grep "host/t11.test1.h5l.se@${R1}" > /dev/null ||
+ { ec=1 ; echo "canonicalized t11 entry not present"; eval "${testfailed}"; }
+
+
+ ${kdestroy}
+fi
+
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-cc.in b/third_party/heimdal/tests/kdc/check-cc.in
new file mode 100644
index 0000000..46e846a
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-cc.in
@@ -0,0 +1,203 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+unset KRB5CCNAME
+
+testfailed="echo test failed; exit 1"
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+pwport=@pwport@
+
+kinit="${kinit} --password-file=${objdir}/foopassword ${afs_no_afslog}"
+kdestroy="${kdestroy} ${afs_no_unlog}"
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+
+server=host/datan.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} add -p foo --use-defaults bar@${R} || exit 1
+${kadmin} add -p kaka --use-defaults ${server}@${R} || exit 1
+${kadmin} ext -k ${keytab} ${server}@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo Starting kdc ; > messages.log
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+echo Starting kcm ; > messages.log
+${kcm} -s ${objdir} --detach || { echo "kcm failed to start"; cat messages.log; exit 1; }
+kcmpid=`getpid kcm`
+
+HEIM_IPC_DIR=${objdir}
+export HEIM_IPC_DIR
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+ec=0
+
+export KRB5CCNAME=SCC:${objdir}/sdb
+
+${kswitch} -p foo@${R} 2>/dev/null && ${kdestroy}
+${kswitch} -p foo@${R} 2>/dev/null && ${kdestroy}
+${kswitch} -p bar@${R} 2>/dev/null && ${kdestroy}
+${kswitch} -p bar@${R} 2>/dev/null && ${kdestroy}
+
+echo "getting default tickets"; > messages.log
+${kinit} foo@${R} || { ec=1 ; eval "${testfailed}"; }
+${kswitch} -p foo@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep foo@ >/dev/null || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "getting both tickets"; > messages.log
+${kinit} -c ${KRB5CCNAME}:1 foo@${R} || { ec=1 ; eval "${testfailed}"; }
+${kinit} -c ${KRB5CCNAME}:2 bar@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "switch foo"
+${kswitch} -p foo@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} | head -2 | grep foo@ >/dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep foo@ >/dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep bar@ >/dev/null || { ec=1 ; eval "${testfailed}"; }
+echo "switch bar"
+${kswitch} -p bar@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} | head -2 | grep bar@ >/dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep foo@ >/dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep bar@ >/dev/null || { ec=1 ; eval "${testfailed}"; }
+echo "delete bar"
+${kdestroy}
+echo "check that bar is gone"
+${klist} -l | grep bar@ >/dev/null && { ec=1 ; eval "${testfailed}"; }
+echo "check that foo is still there"
+${klist} -l | grep foo@ >/dev/null || { ec=1 ; eval "${testfailed}"; }
+${kswitch} -p foo@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "delete foo"
+${kdestroy} || { ec=1 ; eval "${testfailed}"; }
+echo "check that foo is gone"
+${klist} -l | grep foo@ >/dev/null && { ec=1 ; eval "${testfailed}"; }
+echo "check that bar is gone"
+${klist} -l | grep bar@ >/dev/null && { ec=1 ; eval "${testfailed}"; }
+
+echo "getting tickets (KCM)"; > messages.log
+KRB5_CONFIG="${objdir}/krb5-kcm.conf"
+export KRB5_CONFIG
+unset KRB5CCNAME
+${kinit} --default-for-principal foo@${R}
+${kinit} --default-for-principal bar@${R}
+${kinit} bar@${R}
+${klist} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} | grep foo@${R} > /dev/null && { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep foo@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} -c KCM: | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+KRB5CCNAME=KCM: ${klist} | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+if [ -n "$BASH_VERSION" ]; then
+ ${klist} -c KCM:${UID} | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+ ${klist} -c KCM:${UID}: | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+ KRB5CCNAME=KCM:${UID} ${klist} | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+ KRB5CCNAME=KCM:${UID}: ${klist} | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+fi
+${kdestroy} -A
+${klist} 2>/dev/null && { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep bar@${R} > /dev/null && { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep foo@${R} > /dev/null && { ec=1 ; eval "${testfailed}"; }
+${kinit} bar@${R}
+${kinit} --default-for-principal foo@${R}
+${klist} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} | grep foo@${R} > /dev/null && { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} -l | grep foo@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${klist} -c KCM: | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+KRB5CCNAME=KCM: ${klist} | grep bar@${R} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${kdestroy} -A
+
+echo "getting tickets (DIR)"; > messages.log
+KRB5_CONFIG="${objdir}/krb5-cccol.conf"
+export KRB5_CONFIG
+unset KRB5CCNAME
+rm -rf ${objdir}/kt ${objdir}/cc_dir
+mkdir ${objdir}/cc_dir || { ec=1 ; eval "${testfailed}"; }
+${kinit} --default-for-principal foo@${R} || { ec=1 ; eval "${testfailed}"; }
+${kinit} --default-for-principal --no-change-default bar@${R} || { ec=1 ; eval "${testfailed}"; }
+primary=`cat ${objdir}/cc_dir/primary`
+[ "x$primary" = xtkt.foo@${R} ] || { ec=1 ; eval "${testfailed}"; }
+${klist} -l |
+ grep "foo@TEST.H5L.SE.*FILE:${objdir}/cc_dir/tkt.foo@TEST.H5L.SE" > /dev/null ||
+ { ec=1 ; eval "${testfailed}"; }
+${klist} -l |
+ grep "bar@TEST.H5L.SE.*FILE:${objdir}/cc_dir/tkt.bar@TEST.H5L.SE" > /dev/null ||
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "killing kcm (${kcmpid})"
+sh ${leaks_kill} kcm $kcmpid || exit 1
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-delegation.in b/third_party/heimdal/tests/kdc/check-delegation.in
new file mode 100644
index 0000000..fdff0f6
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-delegation.in
@@ -0,0 +1,152 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+R2=TEST2.H5L.SE
+R3=TEST3.H5L.SE
+R4=TEST4.H5L.SE
+
+port=@port@
+
+kadmin="${kadmin} -l -r ${R}"
+kdc="${kdc} --addresses=localhost -P $port"
+
+server=host/datan.test4.h5l.se@TEST4.H5L.ORG
+cache="FILE:${objdir}/cache.krb5"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist="${klist} -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+testfailed="echo test failed; ${klist} -v ; exit 1"
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+initflags="init --realm-max-ticket-life=1day --realm-max-renewable-life=1month"
+
+${kadmin} ${initflags} ${R} || exit 1
+${kadmin} ${initflags} ${R2} || exit 1
+${kadmin} ${initflags} ${R3} || exit 1
+${kadmin} ${initflags} ${R4} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R2}@${R} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R3}@${R2} || exit 1
+${kadmin} add -p cross3 --use-defaults krbtgt/${R4}@${R3} || exit 1
+
+${kadmin} modify --attributes=+ok-as-delegate krbtgt/${R2}@${R} || exit 1
+${kadmin} modify --attributes=+ok-as-delegate krbtgt/${R3}@${R2} || exit 1
+
+${kadmin} add -p foo --use-defaults host/server.test3.h5l.se@${R3} || exit 1
+${kadmin} modify --attributes=+ok-as-delegate host/server.test3.h5l.se@${R3} || exit 1
+${kadmin} add -p foo --use-defaults host/noserver.test3.h5l.se@${R3} || exit 1
+
+${kadmin} add -p foo --use-defaults host/server.test4.h5l.se@${R4} || exit 1
+${kadmin} modify --attributes=+ok-as-delegate host/server.test4.h5l.se@${R4} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+${kadmin} check ${R2} || exit 1
+${kadmin} check ${R3} || exit 1
+${kadmin} check ${R4} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo Starting kdc; > messages.log
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+ec=0
+
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "get cross realm manually"
+${kgetcred} krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} krbtgt/${R3}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} krbtgt/${R4}@${R3} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} host/server.test3.h5l.se@${R3} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} host/server.test4.h5l.se@${R4} || { ec=1 ; eval "${testfailed}"; }
+
+
+echo "check result"
+${klist} -v | awk '/Server:.*host.server.test3/{c=8}{if(c-->0){print}}' | grep 'Ticket flags:.*ok-as-delegate' > /dev/null || \
+ { ec=1 ; echo "server.test3 failed"; eval "${testfailed}"; }
+${klist} -v | awk '/Server:.*host.noserver.test3/{c=8}{if(c-->0){print}}' | grep 'Ticket flags:.*ok-as-delegate' 2> /dev/null && \
+ { ec=1 ; echo "noserver.test3 failed"; eval "${testfailed}"; }
+${klist} -v | awk '/Server:.*host.server.test4/{c=8}{if(c-->0){print}}' | grep 'Ticket flags:.*ok-as-delegate' 2> /dev/null && \
+ { ec=1 ; echo "server.test4 failed" ; eval "${testfailed}"; }
+
+${kdestroy}
+
+#echo "Getting client initial tickets"; > messages.log
+#${kinit} --password-file=${objdir}/foopassword foo@${R} || \
+# { ec=1 ; eval "${testfailed}"; }
+#
+#echo "get cross realm automagicly"
+#${kgetcred} host/server.test4.h5l.se@${R4} || { ec=1 ; eval "${testfailed}"; }
+#
+#echo "check result"
+#${klist} -v | grep -A8 -e 'Server:.*server.test4' | grep 'Ticket flags:.*ok-as-delegate' && { ec=1 ; eval "${testfailed}"; }
+#
+#${kdestroy}
+
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-des.in b/third_party/heimdal/tests/kdc/check-des.in
new file mode 100644
index 0000000..144613d
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-des.in
@@ -0,0 +1,155 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+R2=TEST2.H5L.SE
+
+port=@port@
+
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+
+afsserver=afs/test.h5l.se
+hostserver=host/server.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist="${klist} -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R2} || exit 1
+
+${kadmin} cpw -r krbtgt/${R}@${R} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} add -p kaka --use-defaults ${afsserver}@${R} || exit 1
+${kadmin} add -p kaka --use-defaults ${hostserver}@${R} || exit 1
+${kadmin} add_enctype -r ${afsserver}@${R} des-cbc-crc || exit 1
+${kadmin} add_enctype -r ${hostserver}@${R} des-cbc-crc || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo Starting kdc; > messages.log
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+ec=0
+
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting non des tickets (afs)"; > messages.log
+${kgetcred} ${afsserver}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} -v | grep des-cbc-crc > /dev/null && { ec=1 ; eval "${testfailed}"; }
+echo "Getting non des tickets (host/)"; > messages.log
+${kgetcred} ${hostserver}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} -v | grep des-cbc-crc > /dev/null && { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting des tickets (fail test)"; > messages.log
+${kgetcred} -e des-cbc-crc ${hostserver}@${R} 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting non des tickets"; > messages.log
+${kgetcred} ${afsserver}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} -v | grep des-cbc-crc > /dev/null && { ec=1 ; eval "${testfailed}"; }
+
+
+KRB5_CONFIG="${objdir}/krb5-weak.conf"
+
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting non des tickets (host/), failure test"; > messages.log
+${kgetcred} -e des-cbc-crc ${hostserver}@${R} 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+${klist} -v | grep des-cbc-crc > /dev/null && { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting des tickets (afs)"; > messages.log
+${kgetcred} -e des-cbc-crc ${afsserver}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} -v | grep des-cbc-crc > /dev/null || { ec=1 ; eval "${testfailed}"; }
+
+${kdestroy}
+
+
+
+${kdestroy}
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-digest.in b/third_party/heimdal/tests/kdc/check-digest.in
new file mode 100644
index 0000000..d934f4e
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-digest.in
@@ -0,0 +1,291 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+srcdir="@srcdir@"
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+
+server=host/datan.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+ocache="FILE:${objdir}/ocache.krb5"
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist="${klist} -c $cache"
+kdigest="${kdigest} --ccache=$cache"
+
+username=foo
+userpassword=digestpassword
+
+password=foobarbaz
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p $userpassword --use-defaults ${username}@${R} || exit 1
+${kadmin} add -p $password --use-defaults ${server}@${R} || exit 1
+${kadmin} add -p kaka --use-defaults digest/${R}@${R} || exit 1
+${kadmin} modify --attributes=+allow-digest ${server}@${R} || exit 1
+${kadmin} ext -k ${keytab} ${server}@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo $password > ${objdir}/foopassword
+
+echo "Starting kdc" ; > messages.log
+env ${HEIM_MALLOC_DEBUG} ${kdc} --detach --testing ||
+ { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; cat messages.log; exit 1;" EXIT
+
+exitcode=0
+
+echo "Getting digest server tickets"
+${kinit} --password-file=${objdir}/foopassword ${server}@$R || exitcode=1
+${kdigest} digest-server-init \
+ --kerberos-realm=${R} \
+ --type=CHAP > /dev/null || exitcode=1
+
+echo "Trying NTLM"
+
+NTLM_ACCEPTOR_CCACHE="$cache"
+export NTLM_ACCEPTOR_CCACHE
+
+echo "Trying server-init"
+${kdigest} ntlm-server-init \
+ --kerberos-realm=${R} \
+ > sdigest-init || exitcode=1
+
+echo "test_ntlm"
+${test_ntlm} || { echo "test_ntlm failed"; exit 1; }
+
+NTLM_USER_FILE="${srcdir}/ntlm-user-file.txt"
+export NTLM_USER_FILE
+
+echo "test_context --mech-type=ntlm"
+${test_context} --mech-type=ntlm \
+ --client-name=foo@TEST \
+ --name-type=hostbased-service datan@TEST || \
+ { echo "test_context 1 failed"; exit 1; }
+
+${test_context} --mech-type=ntlm \
+ --client-name=foo@TEST \
+ --name-type=hostbased-service datan@host.TEST || \
+ { echo "test_context 2 failed"; exit 1; }
+
+${test_context} --mech-type=ntlm \
+ --client-name=foo@TEST \
+ --name-type=hostbased-service datan@host.test.domain2 || \
+ { echo "test_context 3 failed"; exit 1; }
+
+echo "Trying SL in NTLM"
+
+
+for type in \
+ "" \
+ "--getverifymic" \
+ "--wrapunwrap" \
+ "--getverifymic --wrapunwrap" \
+ ; do
+
+ echo "Trying NTLM type: ${type}"
+ ${test_context} --mech-type=ntlm ${type} \
+ --client-name=foo@TEST \
+ --name-type=hostbased-service datan@TEST || \
+ { echo "test_context 1 failed"; exit 1; }
+
+done
+
+
+echo "Trying CHAP"
+
+${kdigest} digest-server-init \
+ --kerberos-realm=${R} \
+ --type=CHAP \
+ > sdigest-reply || exitcode=1
+
+snonce=`grep server-nonce= sdigest-reply | cut -f2- -d=`
+identifier=`grep identifier= sdigest-reply | cut -f2- -d=`
+opaque=`grep opaque= sdigest-reply | cut -f2- -d=`
+
+${kdigest} digest-client-request \
+ --type=CHAP \
+ --username="$username" \
+ --password="$userpassword" \
+ --opaque="$opaque" \
+ --server-identifier="$identifier" \
+ --server-nonce="$snonce" \
+ > cdigest-reply || exitcode=1
+
+cresponseData=`grep responseData= cdigest-reply | cut -f2- -d=`
+
+#echo user: $username
+#echo server-nonce: $snonce
+#echo opaqeue: $opaque
+#echo identifier: $identifier
+
+${kdigest} digest-server-request \
+ --kerberos-realm=${R} \
+ --type=CHAP \
+ --username="$username" \
+ --opaque="$opaque" \
+ --client-response="$cresponseData" \
+ --server-identifier="$identifier" \
+ --server-nonce="$snonce" \
+ > s2digest-reply || exitcode=1
+
+status=`grep status= s2digest-reply | cut -f2- -d=`
+
+if test "X$status" = "Xok" ; then
+ echo "CHAP response ok"
+else
+ echo "CHAP response failed"
+ exitcode=1
+fi
+
+cresponseData=`echo $cresponseData | sed 's/..../DEADBEEF/'`
+
+${kdigest} digest-server-request \
+ --kerberos-realm=${R} \
+ --type=CHAP \
+ --username="$username" \
+ --opaque="$opaque" \
+ --client-response="$cresponseData" \
+ --server-identifier="$identifier" \
+ --server-nonce="$snonce" \
+ > s2digest-reply || exitcode=1
+
+status=`grep status= s2digest-reply | cut -f2- -d=`
+
+if test "X$status" = "Xfailed" ; then
+ echo "CHAP response fail as it should"
+else
+ echo "CHAP response succeeded errorously"
+ exitcode=1
+fi
+
+echo "Trying MS-CHAP-V2"
+
+${kdigest} digest-server-init \
+ --kerberos-realm=${R} \
+ --type=MS-CHAP-V2 \
+ > sdigest-reply || exitcode=1
+
+snonce=`grep server-nonce= sdigest-reply | cut -f2- -d=`
+opaque=`grep opaque= sdigest-reply | cut -f2- -d=`
+cnonce="21402324255E262A28295F2B3A337C7E"
+
+echo "MS-CHAP-V2 client request"
+${kdigest} digest-client-request \
+ --type=MS-CHAP-V2 \
+ --username="$username" \
+ --password="$userpassword" \
+ --opaque="$opaque" \
+ --client-nonce="$cnonce" \
+ --server-nonce="$snonce" \
+ > cdigest-reply || exitcode=1
+
+cresponseData=`grep responseData= cdigest-reply | cut -f2- -d=`
+cRsp=`grep AuthenticatorResponse= cdigest-reply | cut -f2- -d=`
+ckey=`grep session-key= cdigest-reply | cut -f2- -d=`
+
+${kdigest} digest-server-request \
+ --kerberos-realm=${R} \
+ --type=MS-CHAP-V2 \
+ --username="$username" \
+ --opaque="$opaque" \
+ --client-response="$cresponseData" \
+ --client-nonce="$cnonce" \
+ --server-nonce="$snonce" \
+ > s2digest-reply || exitcode=1
+
+status=`grep status= s2digest-reply | cut -f2- -d=`
+sRsp=`grep rsp= s2digest-reply | cut -f2- -d=`
+skey=`grep session-key= s2digest-reply | cut -f2- -d=`
+
+if test "X$sRsp" != "X$cRsp" ; then
+ echo "rsp wrong $sRsp != $cRsp"
+ exitcode=1
+fi
+
+if test "X$skey" != "X$ckey" ; then
+ echo "rsp wrong"
+ exitcode=1
+fi
+
+if test "X$status" = "Xok" ; then
+ echo "MS-CHAP-V2 response ok"
+else
+ echo "MS-CHAP-V2 response failed"
+ exitcode=1
+fi
+
+trap "" EXIT
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+exit $exitcode
+
diff --git a/third_party/heimdal/tests/kdc/check-fast.in b/third_party/heimdal/tests/kdc/check-fast.in
new file mode 100644
index 0000000..d1683f2
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-fast.in
@@ -0,0 +1,212 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2011 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+KRB5_CONFIG="${1-${objdir}/krb5.conf}"
+export KRB5_CONFIG
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+
+server=host/datan.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+acache="FILE:${objdir}/acache.krb5"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+akinit="${kinit} -c $acache ${afs_no_afslog}"
+klist="${klist} -c $cache"
+aklist="${klist} -c $acache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} add -p foo --use-defaults ${server}@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo foo > ${objdir}/foopassword
+echo bar > ${objdir}/barpassword
+
+echo Starting kdc ; > messages.log
+env MallocStackLogging=1 MallocStackLoggingNoCompact=1 MallocErrorAbort=1 MallocLogFile=${objdir}/malloc-log \
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; cat messages.log; exit 1;" EXIT
+
+ec=0
+
+#
+# Check armor ticket
+#
+
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Checking for FAST avail"
+${klist} --hidden | grep fast_avail > /dev/null || { exit 1; }
+echo "Getting tickets"; > messages.log
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Listing tickets"; > messages.log
+${klist} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Acquire host ticket to be used as an ARMOR ticket"; > messages.log
+${akinit} --password-file=${objdir}/foopassword ${server}@${R} >/dev/null|| { exit 1; }
+echo "Checking for FAST avail (in the FAST armor cache)"; > messages.log
+${aklist} --hidden | grep fast_avail > /dev/null || { exit 1; }
+
+#
+# Client tests
+#
+
+echo "Getting client initial tickets with FAST armor ticket"; > messages.log
+${kinit} --fast-armor-cache=${acache} \
+ --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting client initial tickets with FAST armor ticket [failure]"; > messages.log
+${kinit} --fast-armor-cache=${acache} \
+ --password-file=${objdir}/barpassword foo@$R 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Checking for FAST avail (in the FAST acquired cache)"; > messages.log
+${klist} --hidden | grep fast_avail > /dev/null || { exit 1; }
+
+echo "Getting service ticket"
+${kgetcred} ${server}@${R} || { exit 1; }
+${kdestroy}
+
+#
+# Test GSS-API pre-authentication using SAnon. It will only succeed where there
+# is FAST armor to authenticate the KDC, otherwise it will fail as SAnon does
+# not provide mutual authentication (GSS_C_MUTUAL_FLAG).
+#
+
+for mech in sanon-x25519 spnego ; do
+ echo "Trying ${mech} pre-authentication with FAST armor"; > messages.log
+ ${kinit} --fast-armor-cache=${acache} \
+ --anonymous --gss-mech=${mech} @$R 2>/dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+
+ echo "Getting service ticket"
+ ${kgetcred} ${server}@${R} || { exit 1; }
+ ${kdestroy}
+
+ echo "Trying ${mech} pre-authentication with anonymous FAST armor"; > messages.log
+ ${kinit} --pk-anon-fast-armor \
+ --anonymous --gss-mech=${mech} @$R 2>/dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+
+ echo "Getting service ticket"
+ ${kgetcred} ${server}@${R} || { exit 1; }
+ ${kdestroy}
+
+ echo "Trying ${mech} pre-authentication with no FAST armor"; > messages.log
+ ${kinit} \
+ --anonymous --gss-mech=${mech} @$R 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+done
+
+#
+# Use MIT client tools
+#
+
+if [ -n "$MITKRB5" -a -f "${MITKRB5}/kinit" ] ; then
+ echo "Running MIT FAST tests"
+
+ kinitpty=${objdir}/foopassword.rkpty
+cat > ${kinitpty} <<EOF
+expect Password
+password foo\n
+EOF
+
+ echo "Acquire host ticket"; > messages.log
+ ${rkpty} ${kinitpty} "${MITKRB5}/kinit" -c ${acache} ${server}@${R} >/dev/null|| { exit 1; }
+ (${aklist} | grep ${server} > /dev/null ) || { exit 1; }
+
+ echo "Checking for FAST avail"; > messages.log
+ ${aklist} --hidden | grep fast_avail > /dev/null || { exit 1; }
+
+ echo "Using plain to get a initial ticket"; > messages.log
+ ${rkpty} ${kinitpty} "${MITKRB5}/kinit" -c ${cache} foo@${R} >/dev/null|| { exit 1; }
+ (${klist} | grep foo > /dev/null ) || { exit 1; }
+
+ echo "Using FAST to get a initial ticket"; > messages.log
+ ${rkpty} ${kinitpty} "${MITKRB5}/kinit" -c ${cache} -T ${acache} foo@${R} >/dev/null || { exit 1; }
+ (${klist} | grep foo > /dev/null ) || { exit 1; }
+
+ echo "Checking for FAST avail"; > messages.log
+ ${klist} --hidden | grep fast_avail > /dev/null || { exit 1; }
+
+ echo "Getting service ticket"; > messages.log
+ "${MITKRB5}/kvno" -c ${cache} ${server}@${R} || { exit 1; }
+
+fi
+
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-hdb-mitdb.in b/third_party/heimdal/tests/kdc/check-hdb-mitdb.in
new file mode 100644
index 0000000..a241aeb
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-hdb-mitdb.in
@@ -0,0 +1,111 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+KRB5_CONFIG="${1-${objdir}/krb5-hdb-mitdb.conf}"
+export KRB5_CONFIG
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+# If there is no ldap support compiled in, disable test
+if ${kdc} --builtin-hdb | grep mit-db > /dev/null ; then
+ :
+else
+ echo "no MIT KDB support"
+ exit 77
+fi
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+
+kadmin="${kadmin} -l -r $R --config-file=${KRB5_CONFIG}"
+kdc="${kdc} --addresses=localhost -P $port"
+
+server=host/datan.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist="${klist} -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Database should exist
+
+${kadmin} ext -k ${keytab} ${server}@${R} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo Starting kdc ; > messages.log
+env MallocStackLogging=1 MallocStackLoggingNoCompact=1 MallocErrorAbort=1 MallocLogFile=${objdir}/malloc-log \
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+ec=0
+
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting tickets"; > messages.log
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Listing tickets"; > messages.log
+${klist} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${test_ap_req} ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-httpkadmind.in b/third_party/heimdal/tests/kdc/check-httpkadmind.in
new file mode 100644
index 0000000..9707fc1
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-httpkadmind.in
@@ -0,0 +1,842 @@
+#!/bin/sh
+#
+# Copyright (c) 2020 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+if ! which curl > /dev/null; then
+ echo "curl is not available -- not testing httpkadmind"
+ exit 77
+fi
+if ! test -x ${objdir}/../../kdc/httpkadmind; then
+ echo "Configured w/o libmicrohttpd -- not testing httpkadmind"
+ exit 77
+fi
+
+R=TEST.H5L.SE
+domain=test.h5l.se
+
+port=@port@
+admport=@admport@
+admport1=@admport@
+admport2=@admport2@
+restport=@restport@
+restport1=@restport@
+restport2=@restport2@
+
+server=datan.test.h5l.se
+otherserver=other.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+cache2="FILE:${objdir}/cache2.krb5"
+admincache="FILE:${objdir}/cache3.krb5"
+keyfile="${hx509_data}/key.der"
+keyfile2="${hx509_data}/key2.der"
+kt=${objdir}/kt
+keytab=FILE:${kt}
+ukt=${objdir}/ukt
+ukeytab=FILE:${ukt}
+
+kdc="${kdc} --addresses=localhost -P $port"
+kadminr="${kadmin} -r $R -a $(uname -n)"
+kadmin="${kadmin} -l -r $R"
+kadmind2="${kadmind} --keytab=${keytab} --detach -p $admport2 --read-only"
+kadmind="${kadmind} --keytab=${keytab} --detach -p $admport"
+httpkadmind2="${httpkadmind} --reverse-proxied -T Negotiate -p $restport2"
+httpkadmind="${httpkadmind} --reverse-proxied -T Negotiate -p $restport1"
+
+kinit2="${kinit} -c $cache2 ${afs_no_afslog}"
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+adminklist="${klist} --hidden -v -c $admincache"
+klist2="${klist} --hidden -v -c $cache2"
+klist="${klist} --hidden -v -c $cache"
+kgetcred2="${kgetcred} -c $cache2"
+kgetcred="${kgetcred} -c $cache"
+kdestroy2="${kdestroy} -c $cache2 ${afs_no_unlog}"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+kx509="${kx509} -c $cache"
+
+KRB5_CONFIG="${objdir}/krb5-httpkadmind.conf"
+export KRB5_CONFIG
+KRB5CCNAME=$cache
+export KRB5CCNAME
+HEIM_PIDFILE_DIR=$objdir
+export HEIM_PIDFILE_DIR
+HEIM_IPC_DIR=$objdir
+export HEIM_IPC_DIR
+
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+rm -f *.pem *.crt *.der
+rm -rf authz_dir
+rm -f extracted_keytab*
+
+mkdir -p authz_dir
+
+> messages.log
+
+# We'll avoid using a KDC for now. For testing /httpkadmind we only need keys
+# for Negotiate tokens, and we'll use ktutil and kimpersonate to make it
+# possible to create and accept those without a KDC.
+
+# grant ext-type value grantee_principal
+grant() {
+ mkdir -p "${objdir}/authz_dir/${3}"
+ touch "${objdir}/authz_dir/${3}/${1}=${2}"
+}
+
+revoke() {
+ rm -rf "${objdir}/authz_dir"
+ mkdir -p "${objdir}/authz_dir"
+}
+
+if set -o|grep 'verbose.*on' > /dev/null ||
+ set -o|grep 'xtrace.*on' > /dev/null; then
+ verbose=-vvv
+else
+ verbose=
+fi
+
+# HTTP curl-opts
+HTTP() {
+ curl -g --resolve ${server}:${restport2}:127.0.0.1 \
+ --resolve ${server}:${restport}:127.0.0.1 \
+ -u: --negotiate $verbose \
+ -D response-headers \
+ "$@"
+}
+
+# get_config QPARAMS curl-opts
+get_config() {
+ url="http://${server}:${restport}/get-config?$1"
+ shift
+ HTTP $verbose "$@" "$url"
+}
+
+check_age() {
+ set -- $(grep -i ^Cache-Control: response-headers)
+ if [ $# -eq 0 ]; then
+ return 1
+ fi
+ shift
+ for param in "$@"; do
+ case "$param" in
+ no-store) true;;
+ max-age=0) return 1;;
+ max-age=*) true;;
+ *) return 1;;
+ esac
+ done
+ return 0;
+}
+
+# get_keytab QPARAMS curl-opts
+get_keytab() {
+ url="http://${server}:${restport}/get-keys?$1"
+ shift
+ HTTP $verbose "$@" "$url"
+}
+
+# get_keytab_POST QPARAMS curl-opts
+get_keytab_POST() {
+ # Curl is awful, so if you don't use -f, you don't get non-zero exit codes on
+ # error responses, but if you do use -f then -D doesn't work. Ugh.
+ #
+ # So first we check that POST w/o CSRF token fails:
+ q=$1
+ shift
+
+ get_keytab "$q" -X POST --data-binary @/dev/null -f "$@" &&
+ { echo "POST succeeded w/o CSRF token!"; return 1; }
+ get_keytab "$q" -X POST --data-binary @/dev/null "$@"
+ grep ^X-CSRF-Token: response-headers >/dev/null || return 1
+ get_keytab "$q" -X POST --data-binary @/dev/null \
+ -H "$(sed -e 's/\r//' response-headers | grep ^X-CSRF-Token:)" "$@"
+ grep '^HTTP/1.1 200' response-headers >/dev/null || return $?
+ return 0
+}
+
+get_keytab_POST_redir() {
+ url="http://${server}:${restport}/get-keys?$1"
+ shift
+ HTTP -X POST --data-binary @/dev/null "$@" "$url"
+ grep ^X-CSRF-Token: response-headers >/dev/null ||
+ { echo "POST w/o CSRF token had response w/o CSRF token!"; return 1; }
+ HTTP -X POST --data-binary @/dev/null -f \
+ -H "$(sed -e 's/\r//' response-headers | grep ^X-CSRF-Token:)" \
+ --location --location-trusted "$@" "$url"
+}
+
+kdcpid=
+httpkadmindpid=
+httpkadmind2pid=
+test_csr_authorizer_pid=
+kadmindpid=
+kadmind2pid=
+cleanup() {
+ test -n "$kdcpid" &&
+ { echo signal killing kdc; kill -9 "$kdcpid"; }
+ test -n "$test_csr_authorizer_pid" &&
+ { echo signal killing test_csr_authorizer; kill -9 "$test_csr_authorizer_pid"; }
+ test -n "$httpkadmindpid" &&
+ { echo signal killing httpkadmind; kill -9 "$httpkadmindpid"; }
+ test -n "$httpkadmind2pid" &&
+ { echo signal killing second httpkadmind; kill -9 "$httpkadmind2pid"; }
+ test -n "$kadmindpid" &&
+ { echo signal killing kadmind; kill -9 "$kadmindpid"; }
+ test -n "$kadmind2pid" &&
+ { echo signal killing kadmind; kill -9 "$kadmind2pid"; }
+}
+trap cleanup EXIT
+
+rm -f extracted_keytab
+
+echo "Creating database"
+rm -f $kt $ukt
+${kadmin} <<EOF || exit 1
+init --realm-max-ticket-life=1day --realm-max-renewable-life=1month ${R}
+add -r --use-defaults foo@${R}
+add -r --use-defaults httpkadmind/admin@${R}
+add -r --use-defaults WELLKNOWN/CSRFTOKEN@${R}
+add -r --use-defaults HTTP/localhost@${R}
+add -r --use-defaults host/xyz.${domain}@${R}
+add -r --use-defaults HTTP/xyz.${domain}@${R}
+add_ns --key-rotation-epoch=-1d --key-rotation-period=5m \
+ --max-ticket-life=1d --max-renewable-life=5d \
+ --attributes= HTTP/ns.${domain}@${R}
+add_ns --key-rotation-epoch=-1d --key-rotation-period=5m \
+ --max-ticket-life=1d --max-renewable-life=5d \
+ --attributes=ok-as-delegate host/.ns2.${domain}@${R}
+add -r --use-defaults HTTP/${server}@${R}
+ext_keytab -r -k $keytab kadmin/admin@${R}
+ext_keytab -r -k $keytab httpkadmind/admin@${R}
+ext_keytab -r -k $keytab HTTP/${server}@${R}
+ext_keytab -r -k $keytab HTTP/localhost@${R}
+add -r --use-defaults HTTP/${otherserver}@${R}
+ext_keytab -r -k $ukeytab foo@${R}
+EOF
+${kdestroy}
+
+# For a while let's not bother with a KDC
+$kimpersonate --ccache=$cache -k $keytab -R -t aes128-cts-hmac-sha1-96 \
+ -c foo@${R} -s HTTP/datan.test.h5l.se@${R} ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+$kimpersonate -A --ccache=$cache -k $keytab -R -t aes128-cts-hmac-sha1-96 \
+ -c foo@${R} -s HTTP/localhost@${R} ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+$klist -t >/dev/null ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+
+echo "Starting test_csr_authorizer"
+${test_csr_authorizer} -A $objdir/authz_dir -S $objdir --server --daemon ||
+ { echo "test_csr_authorizer failed to start"; exit 2; }
+test_csr_authorizer_pid=`getpid test_csr_authorizer`
+ec=0
+
+echo "Starting httpkadmind"
+${httpkadmind} -H $server -H localhost --local -t --daemon ||
+ { echo "httpkadmind failed to start"; exit 2; }
+httpkadmindpid=`getpid httpkadmind`
+ec=0
+
+echo "Checking that concrete principal exists"
+${kadmin} get HTTP/xyz.${domain} > /dev/null ||
+ { echo "Failed to create HTTP/xyz.${domain}"; exit 1; }
+echo "Checking that virtual principal exists"
+${kadmin} get HTTP/foo.ns.${domain} > /dev/null ||
+ { echo "Virtual principals not working"; exit 1; }
+
+hn=xyz.${domain}
+p=HTTP/$hn
+echo "Fetching krb5.conf for $p"
+get_config "princ=$p" -sf -o "${objdir}/extracted_config" ||
+ { echo "Failed to get config for $p"; exit 1; }
+read config < "${objdir}/extracted_config"
+test "$config" = "include /etc/krb5.conf" ||
+ { echo "Got unexpected default config for $p"; exit 1; }
+${kadmin} mod --krb5-config-file="$KRB5_CONFIG" $p ||
+ { echo "Failed to set config for $p"; exit 1; }
+get_config "princ=$p" -sf -o "${objdir}/extracted_config" ||
+ { echo "Failed to get config for $p"; exit 1; }
+cmp "${objdir}/extracted_config" "$KRB5_CONFIG" ||
+ { echo "Got unexpected config for $p"; exit 1; }
+
+hn=xyz.${domain}
+p=HTTP/$hn
+echo "Fetching keytab for concrete principal $p"
+rm -f extracted_keytab*
+grant san_dnsname $hn foo@${R}
+${kadmin} ext_keytab -k extracted_keytab $p ||
+ { echo "Failed to get a keytab for $p with kadmin"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.kadmin ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+get_keytab "dNSName=${hn}" -sf -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.kadmin extracted_keytab.rest ||
+ { echo "Keytabs for $p don't match!"; exit 1; }
+
+hn=foo.ns.${domain}
+p=HTTP/$hn
+echo "Fetching keytab for virtual principal $p"
+rm -f extracted_keytab*
+grant san_dnsname $hn foo@${R}
+${kadmin} ext_keytab -k extracted_keytab $p ||
+ { echo "Failed to get a keytab for $p with kadmin"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.kadmin ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+get_keytab "dNSName=${hn}" -sf -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+check_age
+grep -i ^Cache-Control response-headers
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.kadmin extracted_keytab.rest ||
+ { echo "Keytabs for $p don't match!"; exit 1; }
+
+hn1=foo.ns.${domain}
+hn2=foobar.ns.${domain}
+hn3=xyz.${domain}
+p1=HTTP/$hn1
+p2=HTTP/$hn2
+p3=HTTP/$hn3
+echo "Fetching keytabs for more than one principal"
+rm -f extracted_keytab*
+grant san_dnsname $hn1 foo@${R}
+grant san_dnsname $hn2 foo@${R}
+grant san_dnsname $hn3 foo@${R}
+# Note that httpkadmind will first process dNSName q-params, then the spn
+# q-params.
+${kadmin} ext_keytab -k extracted_keytab $p1 ||
+ { echo "Failed to get a keytab for $p1 with kadmin"; exit 1; }
+${kadmin} ext_keytab -k extracted_keytab $p3 ||
+ { echo "Failed to get a keytab for $p3 with kadmin"; exit 1; }
+${kadmin} ext_keytab -k extracted_keytab $p2 ||
+ { echo "Failed to get a keytab for $p2 with kadmin"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.kadmin ||
+ { echo "Failed to list keytab for multiple principals"; exit 1; }
+get_keytab "dNSName=${hn1}&spn=${p2}&dNSName=${hn3}" -sf -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for multiple principals with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.kadmin extracted_keytab.rest ||
+ { echo "Keytabs for $p don't match!"; exit 1; }
+grep $hn1 extracted_keytab.rest > /dev/null ||
+ { echo "Keytab does not include keys for $p1"; exit 1; }
+grep $hn2 extracted_keytab.rest > /dev/null ||
+ { echo "Keytab does not include keys for $p2"; exit 1; }
+grep $hn3 extracted_keytab.rest > /dev/null ||
+ { echo "Keytab does not include keys for $p3"; exit 1; }
+
+p=host/foo.ns.${domain}
+echo "Checking that $p doesn't exist (no namespace for host service)"
+get_keytab "svc=host&dNSName=foo.ns.${domain}" -sf -o "${objdir}/extracted_keytab.rest" &&
+ { echo "Got a keytab for host/foo.ns.${domain} when not namespaced!"; }
+
+echo "Checking that authorization is enforced"
+revoke
+get_keytab "dNSName=xyz.${domain}" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "Got a keytab for HTTP/xyz.${domain} when not authorized!"; exit 1; }
+get_keytab "dNSName=foo.ns.${domain}" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "Got a keytab for HTTP/foo.ns.${domain} when not authorized!"; exit 1; }
+
+echo "Checking that host service keys are not served"
+hn=xyz.${domain}
+p=host/$hn
+echo "Fetching keytab for virtual principal $p"
+rm -f extracted_keytab*
+grant san_dnsname $hn foo@${R}
+get_keytab "service=host&dNSName=xyz.${domain}" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "Got a keytab for $p even though it is a host service!"; exit 1; }
+get_keytab "spn=host/xyz.${domain}" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "Got a keytab for $p even though it is a host service!"; exit 1; }
+revoke
+
+hn=xyz.${domain}
+p=HTTP/$hn
+echo "Checking key rotation for concrete principal $p"
+rm -f extracted_keytab*
+grant san_dnsname $hn foo@${R}
+get_keytab "dNSName=${hn}" -sf -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest1 ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+test "$(grep $p extracted_keytab.rest1 | wc -l)" -eq 1 ||
+ { echo "Wrong number of new keys!"; exit 1; }
+get_keytab "dNSName=${hn}&rotate=true" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "GET succeeded for write operation!"; exit 1; }
+get_keytab_POST "dNSName=${hn}&rotate=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to rotate keys for $p"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest2 ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.rest1 extracted_keytab.rest2 > /dev/null &&
+ { echo "Keys for $p did not change!"; exit 1; }
+test "$(grep $p extracted_keytab.rest2 | wc -l)" -eq 2 ||
+ { echo "Wrong number of new keys!"; exit 1; }
+
+hn=xyz.${domain}
+p=HTTP/$hn
+echo "Checking key rotation w/ revocation for concrete principal $p"
+rm -f extracted_keytab*
+grant san_dnsname $hn foo@${R}
+get_keytab "dNSName=${hn}" -sf -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest1 ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+get_keytab "dNSName=${hn}&revoke=true" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "GET succeeded for write operation!"; exit 1; }
+get_keytab_POST "dNSName=${hn}&revoke=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest2 ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.rest1 extracted_keytab.rest2 > /dev/null &&
+ { echo "Keys for $p did not change!"; exit 1; }
+test "$(grep $p extracted_keytab.rest2 | wc -l)" -eq 1 ||
+ { echo "Wrong number of new keys!"; exit 1; }
+
+hn=abc.${domain}
+p=HTTP/$hn
+echo "Checking concrete principal creation ($p)"
+rm -f extracted_keytab
+grant san_dnsname $hn foo@${R}
+get_keytab "dNSName=${hn}&create=true" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "GET succeeded for write operation!"; exit 1; }
+get_keytab_POST "dNSName=${hn}&create=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+rm -f extracted_keytab
+${kadmin} ext_keytab -k extracted_keytab $p ||
+ { echo "Failed to get a keytab for $p with kadmin"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.kadmin ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.kadmin extracted_keytab.rest ||
+ { echo "Keytabs for $p don't match!"; exit 1; }
+
+hn=bar.ns.${domain}
+p=HTTP/$hn
+echo "Checking materialization of virtual principal ($p)"
+rm -f extracted_keytab
+grant san_dnsname $hn foo@${R}
+get_keytab "dNSName=${hn}&materialize=true" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "GET succeeded for write operation!"; exit 1; }
+get_keytab_POST "dNSName=${hn}&materialize=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to materialize and get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+rm -f extracted_keytab
+${kadmin} ext_keytab -k extracted_keytab $p ||
+ { echo "Failed to get a keytab for $p with kadmin"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.kadmin ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.kadmin extracted_keytab.rest ||
+ { echo "Keytabs for $p don't match!"; exit 1; }
+
+echo "Starting secondary httpkadmind to test HTTP redirection"
+${httpkadmind2} --primary-server-uri=http://localhost:$restport \
+ -H $server --local --local-read-only -t --daemon ||
+ { echo "httpkadmind failed to start"; exit 2; }
+httpkadmind2pid=`getpid httpkadmind`
+ec=0
+
+hn=def.${domain}
+p=HTTP/$hn
+restport=$restport2
+echo "Checking principal creation at secondary yields redirect"
+rm -f extracted_keytab
+grant san_dnsname $hn foo@${R}
+get_keytab_POST_redir "dNSName=${hn}&create=true" \
+ -s -o "${objdir}/extracted_keytab"
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+rm -f extracted_keytab
+${kadmin} ext_keytab -k extracted_keytab $p ||
+ { echo "Failed to get a keytab for $p with kadmin"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.kadmin ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.kadmin extracted_keytab.rest ||
+ { echo "Keytabs for $p don't match!"; exit 1; }
+
+echo "killing httpkadmind (${httpkadmindpid} ${httpkadmind2pid})"
+sh ${leaks_kill} httpkadmind $httpkadmindpid || ec=1
+sh ${leaks_kill} httpkadmind $httpkadmind2pid || ec=1
+httpkadmindpid=
+httpkadmind2pid=
+test $ec = 1 &&
+ { echo "Error killing httpkadmind instances or memory errors found"; exit 1; }
+
+echo "Starting primary kadmind for testing httpkadmind with remote HDB"
+${kadmind} ||
+ { echo "Read-write kadmind failed to start"; exit 2; }
+kadmindpid=`getpid kadmind`
+echo "Starting secondray (read-only) kadmind for testing httpkadmind with remote HDB"
+${kadmind2} ||
+ { echo "Read-only kadmind failed to start"; exit 2; }
+kadmind2pid=`getpid kadmind`
+
+# Make a ccache for use with kadmin(1)
+$kimpersonate --ticket-flags=initial --ccache=$admincache -k $keytab -t aes128-cts-hmac-sha1-96 \
+ -c httpkadmind/admin@${R} -s kadmin/admin@${R} ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+$adminklist -t >/dev/null ||
+ { echo "failed to setup kimpersonate credentials"; exit 2; }
+
+
+echo "Making PKINIT certs for KDC"
+${hxtool} issue-certificate \
+ --self-signed \
+ --issue-ca \
+ --ca-private-key=FILE:${keyfile} \
+ --subject="CN=CA,DC=test,DC=h5l,DC=se" \
+ --certificate="FILE:ca.crt" || exit 1
+${hxtool} request-create \
+ --subject="CN=kdc,DC=test,DC=h5l,DC=se" \
+ --key=FILE:${keyfile2} \
+ req-kdc.der || exit 1
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-kdc" \
+ --pk-init-principal="krbtgt/TEST.H5L.SE@TEST.H5L.SE" \
+ --req="PKCS10:req-kdc.der" \
+ --certificate="FILE:kdc.crt" || exit 1
+${hxtool} request-create \
+ --subject="CN=bar,DC=test,DC=h5l,DC=se" \
+ --key=FILE:${keyfile2} \
+ req-pkinit.der ||
+ { echo "Failed to make CSR for PKINIT client cert"; exit 1; }
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --pk-init-principal="host/synthesized.${domain}@$R" \
+ --req="PKCS10:req-pkinit.der" \
+ --lifetime=7d \
+ --certificate="FILE:pkinit-synthetic.crt" ||
+ { echo "Failed to make PKINIT client cert"; exit 1; }
+
+echo "Starting kdc needed for httpkadmind authentication to kadmind"
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+echo "Starting httpkadmind with remote HDBs only"
+restport=$restport1
+${httpkadmind} -H $server -H localhost -t --daemon \
+ --writable-admin-server=$(uname -n):$admport \
+ --read-only-admin-server=$(uname -n):$admport2 \
+ --kadmin-client-name=httpkadmind/admin@${R} \
+ --kadmin-client-keytab=$keytab ||
+ { echo "httpkadmind failed to start"; exit 2; }
+httpkadmindpid=`getpid httpkadmind`
+ec=0
+
+hn=xyz.${domain}
+p=HTTP/$hn
+echo "Fetching keytab for concrete principal $p using remote HDB"
+rm -f extracted_keytab*
+grant san_dnsname $hn httpkadmind/admin@${R}
+KRB5CCNAME=$admincache ${kadmin} ext_keytab -k extracted_keytab $p ||
+ { echo "Failed to get a keytab for $p with kadmin"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.kadmin ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+get_keytab "spn=${p}" -sf -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.kadmin extracted_keytab.rest ||
+ { echo "Keytabs for $p don't match!"; exit 1; }
+
+hn=xyz.${domain}
+p=HTTP/$hn
+echo "Checking key rotation for concrete principal $p using remote HDB"
+rm -f extracted_keytab*
+grant san_dnsname $hn foo@${R}
+get_keytab "dNSName=${hn}" -sf -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest1 ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+test "$(grep $p extracted_keytab.rest1 | wc -l)" -eq 1 ||
+ { echo "Wrong number of new keys!"; exit 1; }
+get_keytab "dNSName=${hn}&rotate=true" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "GET succeeded for write operation!"; exit 1; }
+get_keytab_POST "dNSName=${hn}&rotate=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to rotate keys for $p"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest2 ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.rest1 extracted_keytab.rest2 > /dev/null &&
+ { echo "Keys for $p did not change!"; exit 1; }
+test "$(grep $p extracted_keytab.rest2 | wc -l)" -eq 2 ||
+ { echo "Wrong number of new keys!"; exit 1; }
+
+sh ${leaks_kill} httpkadmind $httpkadmindpid || ec=1
+httpkadmindpid=
+
+echo "Starting httpkadmind with local read-only HDB and remote read-write HDB"
+${httpkadmind} -H $server -H localhost -t --daemon \
+ --local-read-only \
+ --writable-admin-server=$(uname -n):$admport \
+ --kadmin-client-name=httpkadmind/admin@${R} \
+ --kadmin-client-keytab=$keytab ||
+ { echo "httpkadmind failed to start"; exit 2; }
+httpkadmindpid=`getpid httpkadmind`
+ec=0
+
+hn=xyz.${domain}
+p=HTTP/$hn
+echo "Fetching keytab for concrete principal $p using local read-only HDB"
+rm -f extracted_keytab*
+grant san_dnsname $hn httpkadmind/admin@${R}
+KRB5CCNAME=$admincache ${kadmin} ext_keytab -k extracted_keytab $p ||
+ { echo "Failed to get a keytab for $p with kadmin"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.kadmin ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+get_keytab "spn=${p}" -sf -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.kadmin extracted_keytab.rest ||
+ { echo "Keytabs for $p don't match!"; exit 1; }
+
+hn=xyz.${domain}
+p=HTTP/$hn
+echo "Checking key rotation for concrete principal $p using local read-only HDB and remote HDB"
+rm -f extracted_keytab*
+grant san_dnsname $hn foo@${R}
+get_keytab "dNSName=${hn}" -sf -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to get a keytab for $p with curl"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest1 ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+test "$(grep $p extracted_keytab.rest1 | wc -l)" -eq 2 ||
+ { echo "Wrong number of new keys!"; exit 1; }
+get_keytab "dNSName=${hn}&rotate=true" -sf -o "${objdir}/extracted_keytab" &&
+ { echo "GET succeeded for write operation!"; exit 1; }
+get_keytab_POST "dNSName=${hn}&rotate=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to rotate keys for $p"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list --keys > extracted_keytab.rest2 ||
+ { echo "Failed to list keytab for $p"; exit 1; }
+cmp extracted_keytab.rest1 extracted_keytab.rest2 > /dev/null &&
+ { echo "Keys for $p did not change!"; exit 1; }
+test "$(grep $p extracted_keytab.rest2 | wc -l)" -eq 3 ||
+ { echo "Wrong number of new keys!"; exit 1; }
+
+echo "Checking that host services as clients can self-create"
+hn=synthesized.${domain}
+p=host/$hn
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null &&
+ { echo "Internal error -- $p exists too soon"; exit 1; }
+${kinit2} -C "FILE:${objdir}/pkinit-synthetic.crt,${keyfile2}" ${p}@${R} || \
+ { echo "Failed to kinit with PKINIT client cert"; exit 1; }
+${kgetcred2} HTTP/localhost@$R || echo WAT
+rm -f extracted_keytab*
+KRB5CCNAME=$cache2 \
+get_keytab_POST "spn=$p&create=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list > /dev/null ||
+ { echo "Failed to create and extract host keys for self (bogus keytab)"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+
+echo "Checking that host services can't get other host service principals"
+hn=nonexistent.${domain}
+p=host/$hn
+KRB5CCNAME=$cache2 \
+get_keytab_POST "spn=$p&create=true" -s -o "${objdir}/extracted_keytab2" &&
+ { echo "Failed to fail to create and extract host keys for other!"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab2" list > /dev/null || true
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null &&
+ { echo "Failed to fail to create and extract host keys for other!"; exit 1; }
+
+echo "Checking that host services can't get keys for themselves and others"
+hn=synthesized.${domain}
+p=host/$hn
+p2=host/nonexistent.${domain}
+${kinit2} -C "FILE:${objdir}/pkinit-synthetic.crt,${keyfile2}" ${p}@${R} || \
+ { echo "Failed to kinit with PKINIT client cert"; exit 1; }
+${kgetcred2} HTTP/localhost@$R || echo WAT
+rm -f extracted_keytab*
+KRB5CCNAME=$cache2 \
+get_keytab_POST "spn=$p&spn=$p2&create=true" -s -o "${objdir}/extracted_keytab" &&
+ { echo "Failed to fail to create and extract host keys for other!"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab2" list > /dev/null || true
+KRB5CCNAME=$admincache ${kadmin} get -s $p2 >/dev/null &&
+ { echo "Failed to fail to create and extract host keys for other!"; exit 1; }
+
+echo "Checking that attributes for new principals can be configured"
+hn=a-particular-hostname.test.h5l.se
+p=host/$hn
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --pk-init-principal="$p@$R" \
+ --req="PKCS10:req-pkinit.der" \
+ --lifetime=7d \
+ --certificate="FILE:pkinit-synthetic.crt" ||
+ { echo "Failed to make PKINIT client cert"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null 2>&1 &&
+ { echo "Internal error -- $p exists too soon"; exit 1; }
+${kinit2} -C "FILE:${objdir}/pkinit-synthetic.crt,${keyfile2}" ${p}@${R} || \
+ { echo "Failed to kinit with PKINIT client cert"; exit 1; }
+${kgetcred2} HTTP/localhost@$R || echo WAT
+rm -f extracted_keytab*
+KRB5CCNAME=$cache2 \
+get_keytab_POST "spn=$p&create=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list > /dev/null ||
+ { echo "Failed to create and extract host keys for self (bogus keytab)"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get $p |
+ grep 'Attributes:.*ok-as-delegate' > /dev/null ||
+ { echo "Failed to create with configured attributes"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get $p |
+ grep 'Attributes:.*no-auth-data-reqd' > /dev/null ||
+ { echo "Failed to create with configured attributes"; exit 1; }
+
+hn=other-hostname.test.h5l.se
+p=host/$hn
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --pk-init-principal="$p@$R" \
+ --req="PKCS10:req-pkinit.der" \
+ --lifetime=7d \
+ --certificate="FILE:pkinit-synthetic.crt" ||
+ { echo "Failed to make PKINIT client cert"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null 2>&1 &&
+ { echo "Internal error -- $p exists too soon"; exit 1; }
+${kinit2} -C "FILE:${objdir}/pkinit-synthetic.crt,${keyfile2}" ${p}@${R} || \
+ { echo "Failed to kinit with PKINIT client cert"; exit 1; }
+${kgetcred2} HTTP/localhost@$R || echo WAT
+rm -f extracted_keytab*
+KRB5CCNAME=$cache2 \
+get_keytab_POST "spn=$p&create=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list > /dev/null ||
+ { echo "Failed to create and extract host keys for self (bogus keytab)"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get $p |
+ grep 'Attributes:.*ok-as-delegate' > /dev/null &&
+ { echo "Create with unexpected attributes"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get $p |
+ grep 'Attributes:.*no-auth-data-reqd' > /dev/null &&
+ { echo "Create with unexpected attributes"; exit 1; }
+
+hn=a-server.prod.test.h5l.se
+p=host/$hn
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --pk-init-principal="$p@$R" \
+ --req="PKCS10:req-pkinit.der" \
+ --lifetime=7d \
+ --certificate="FILE:pkinit-synthetic.crt" ||
+ { echo "Failed to make PKINIT client cert"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null 2>&1 &&
+ { echo "Internal error -- $p exists too soon"; exit 1; }
+${kinit2} -C "FILE:${objdir}/pkinit-synthetic.crt,${keyfile2}" ${p}@${R} || \
+ { echo "Failed to kinit with PKINIT client cert"; exit 1; }
+${kgetcred2} HTTP/localhost@$R || echo WAT
+rm -f extracted_keytab*
+KRB5CCNAME=$cache2 \
+get_keytab_POST "spn=$p&create=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list > /dev/null ||
+ { echo "Failed to create and extract host keys for self (bogus keytab)"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get $p |
+ grep 'Attributes:.*ok-as-delegate' > /dev/null ||
+ { echo "Failed to create with configured attributes"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get $p |
+ grep 'Attributes:.*no-auth-data-reqd' > /dev/null ||
+ { echo "Failed to create with configured attributes"; exit 1; }
+
+hn=a-host.ns2.test.h5l.se
+p=host/$hn
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --pk-init-principal="$p@$R" \
+ --req="PKCS10:req-pkinit.der" \
+ --lifetime=7d \
+ --certificate="FILE:pkinit-synthetic.crt" ||
+ { echo "Failed to make PKINIT client cert"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null 2>&1 &&
+ { echo "Internal error -- $p exists too soon"; exit 1; }
+${kinit2} -C "FILE:${objdir}/pkinit-synthetic.crt,${keyfile2}" ${p}@${R} || \
+ { echo "Failed to kinit with PKINIT client cert"; exit 1; }
+${kgetcred2} HTTP/localhost@$R || echo WAT
+rm -f extracted_keytab*
+KRB5CCNAME=$cache2 \
+get_keytab_POST "spn=$p&create=true" -s -o "${objdir}/extracted_keytab" ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+${ktutil} -k "${objdir}/extracted_keytab" list > /dev/null ||
+ { echo "Failed to create and extract host keys for self (bogus keytab)"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get -s $p >/dev/null ||
+ { echo "Failed to create and extract host keys for self"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get $p |
+ grep 'Attributes:.*ok-as-delegate' > /dev/null ||
+ { echo "Failed to create with namespace attributes"; exit 1; }
+KRB5CCNAME=$admincache ${kadmin} get $p |
+ grep 'Attributes:.*no-auth-data-reqd' > /dev/null &&
+ { echo "Create with unexpected attributes"; exit 1; }
+
+grep 'Internal error' messages.log &&
+ { echo "Internal errors in log"; exit 1; }
+
+sh ${leaks_kill} test_csr_authorizer $test_csr_authorizer_pid || ec=1
+sh ${leaks_kill} httpkadmind $httpkadmindpid || ec=1
+sh ${leaks_kill} kadmind $kadmindpid || ec=1
+sh ${leaks_kill} kadmind $kadmind2pid || ec=1
+sh ${leaks_kill} kdc $kdcpid || ec=1
+
+if [ $ec = 0 ]; then
+ trap "" EXIT
+ echo "Success"
+fi
+
+# TODO
+#
+# - implement and test that we can materialize a principal yet leave it with
+# virtual keys
+# - test new key delay? this one is tricky
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-iprop.in b/third_party/heimdal/tests/kdc/check-iprop.in
new file mode 100644
index 0000000..5243793
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-iprop.in
@@ -0,0 +1,611 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+db_type=@db_type@
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+
+# Don't run this test in AFS, since it lacks support for AF_UNIX
+expr "X`/bin/pwd || pwd`" : "X/afs/.*" > /dev/null 2>/dev/null && exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+ipropport=@ipropport@
+ipropport2=@ipropport2@
+
+cache="FILE:${objdir}/cache.krb5"
+keytabfile=${objdir}/iprop.keytab
+keytab="FILE:${keytabfile}"
+
+kdc="${kdc} --addresses=localhost -P $port"
+kadmin="${kadmin} -r $R"
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+
+# We'll test iprop, and in particular, hierarchical iprop. This means we'll
+# have a setup like:
+#
+# ipropd-master -> ipropd-slave -> 2nd ipropd-master -> 2nd ipropd-slave
+
+# Waiting for incremental propagation is inherently difficult because we don't
+# have a way for ipropd-slave to signal this script that it has received
+# updates. Well, it does have a way to signal a possible ipropd-master for
+# hierarchical iprop, but we don't have a way to get that signal here.
+#
+# FIXME: Add a private interface for async waiting for iprop.
+#
+# What we do is we have a set of utility functions:
+#
+# - get_iprop_ver [N] -> checks that N (default to 1) ops have made it over
+# - get_iprop_ver2 [N] -> same, but for second ipropd-slave instance
+#
+# - wait_for -> repeat a command until it succeeds or too many tries
+# - wait_for_slave [N] -> wait for N ops to make it over (calls get_iprop_ver)
+# - wait_for_slave2 [N] -> same, but for second ipropd-slave instance
+#
+# In particular the wait_for* functions busy-wait for a max amount of time,
+# with sleeps in between.
+#
+# NOTE: get_iprop_ver and get_iprop_ver2 keep hidden state.
+#
+# When first called, get_iprop_ver / get_iprop_ver2 save the current version
+# numbers. Thereafter they check that N ops have been received.
+#
+# It is critical to account for every incremental op via get_iprop_ver /
+# get_iprop_ver2, or wait_for_slave / wait_for_slave2, otherwise this test will
+# be racy and will have spurious failures!
+#
+# The pattern should be something like this:
+#
+# echo "Add host"
+# ${kadmin} -l add --random-key --use-defaults host/foo@${R} || exit 1
+# wait_for_slave
+# ^^^^^^^^^^^^^^
+# waits for 1 operation
+#
+# or
+#
+# echo "Rollover host keys"
+# ${kadmin} -l cpw -r --keepold host/foo@${R} || exit 1
+# ${kadmin} -l cpw -r --keepold host/foo@${R} || exit 1
+# ${kadmin} -l cpw -r --keepold host/foo@${R} || exit 1
+# wait_for_slave 3
+# ^^^^^^^^^^^^^^^^
+# waits for the three operations
+#
+# So though all operations must be accounted for, they need not be accounted
+# one by one.
+
+slave_ver_from_master_old=
+slave_ver_from_master_new=
+slave_ver_old=
+slave_ver_new=
+get_iprop_ver () {
+ min_change=${1:-1}
+ slave_ver_from_master_new=`grep '^iprop/' iprop-stats | head -1 | awk '{print $3}'`
+ slave_ver_new=`grep 'up-to-date with version:' iprop-slave-status | awk '{print $4}'`
+ if [ -z "$slave_ver_from_master_new" -o -z "$slave_ver_new" ]; then
+ return 1
+ fi
+ if [ x"$slave_ver_from_master_new" != x"$slave_ver_new" ]; then
+ return 1
+ fi
+ if [ x"$slave_ver_from_master_old" != x ]; then
+ change=`expr "$slave_ver_from_master_new" - "$slave_ver_from_master_old"`
+ if [ "$change" -lt "$min_change" ]; then
+ return 1
+ fi
+ fi
+ slave_ver_from_master_old=$slave_ver_from_master_new
+ slave_ver_old=$slave_ver_new
+ return 0
+}
+
+slave_ver_from_master_old2=
+slave_ver_from_master_new2=
+slave_ver_old2=
+slave_ver_new2=
+get_iprop_ver2 () {
+ min_change=${1:-1}
+ slave_ver_from_master_new2=`grep '^iprop/' iprop-stats2 | head -1 | awk '{print $3}'`
+ slave_ver_new2=`grep 'up-to-date with version:' iprop-slave-status2 | awk '{print $4}'`
+ if [ -z "$slave_ver_from_master_new2" -o -z "$slave_ver_new2" ]; then
+ return 1
+ fi
+ if [ x"$slave_ver_from_master_new2" != x"$slave_ver_new2" ]; then
+ return 1
+ fi
+ if [ x"$slave_ver_from_master_old2" != x ]; then
+ change=`expr "$slave_ver_from_master_new2" - "$slave_ver_from_master_old2"`
+ if [ "$change" -lt "$min_change" ]; then
+ return 1
+ fi
+ fi
+ slave_ver_from_master_old2=$slave_ver_from_master_new2
+ slave_ver_old2=$slave_ver_new2
+ return 0
+}
+
+waitsec=65
+sleeptime=2
+wait_for () {
+ msg=$1
+ shift
+ t=0
+ while ! "$@"; do
+ sleep $sleeptime;
+ t=`expr $t + $sleeptime`
+ if [ $t -gt $waitsec ]; then
+ echo "Waited too long for $msg"
+ exit 1
+ fi
+ done
+ return 0
+}
+
+check_pidfile_is_dead () {
+ if test ! -f lt-${1}.pid -a ! -f ${1}.pid; then
+ return 0
+ fi
+ _pid=`cat lt-${1}.pid ${1}.pid 2>/dev/null`
+ if [ -z "$_pid" ]; then
+ return 0
+ fi
+ if kill -0 $_pid 2>/dev/null; then
+ return 1
+ fi
+ return 0
+}
+
+wait_for_slave () {
+ wait_for "iprop versions to change and/or slave to catch up" get_iprop_ver "$@"
+}
+
+wait_for_slave2 () {
+ wait_for "iprop versions to change and/or second slave to catch up" get_iprop_ver2 "$@"
+}
+
+wait_for_master_down () {
+ wait_for "master to exit" check_pidfile_is_dead ipropd-master
+}
+
+wait_for_slave_down () {
+ wait_for "slave to exit" check_pidfile_is_dead ipropd-slave
+}
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f current*.log
+rm -f out-*
+rm -f mkey.file*
+rm -f messages.log messages.log
+
+> messages.log
+> messages.log2
+
+echo Creating database
+${kadmin} -l \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} -l add -p foo --use-defaults user@${R} || exit 1
+
+${kadmin} -l add --random-key --use-defaults iprop/localhost@${R} || exit 1
+${kadmin} -l ext -k ${keytab} iprop/localhost@${R} || exit 1
+${kadmin} -l add --random-key --use-defaults iprop/slave.test.h5l.se@${R} || exit 1
+${kadmin} -l ext -k ${keytab} iprop/slave.test.h5l.se@${R} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo "Test log recovery"
+${kadmin} -l add --random-key --use-defaults recovtest@${R} || exit 1
+# Test theory: save the log, make a change and save the record it
+# produced, restore the log, append to it the saved record, then add dummy
+# record.
+
+# Save the log
+cp current.log current.log.tmp
+ls -l current.log.tmp | awk '{print $5}' > tmp
+read sz < tmp
+# Make a change
+${kadmin} -l mod -a requires-pre-auth recovtest@${R} || exit 1
+${kadmin} -l get recovtest@${R} | grep 'Attributes: requires-pre-auth$' > /dev/null || exit 1
+# Save the resulting log record
+ls -l current.log | awk '{print $5}' > tmp
+read nsz < tmp
+rm tmp
+dd bs=1 if=current.log skip=$sz of=current.log.tmp.saved-record count=`expr $nsz - $sz` 2>/dev/null
+# Undo the change
+${kadmin} -l mod -a -requires-pre-auth recovtest@${R} || exit 1
+${kadmin} -l get recovtest@${R} | grep 'Attributes:.$' > /dev/null || exit 1
+# Restore the log
+cp current.log current.log.save
+mv current.log.tmp current.log
+# Append the saved record
+cat current.log.tmp.saved-record >> current.log
+rm current.log.tmp.saved-record
+# Check that we still see the principal as modified after another write forcing
+# log recovery.
+${kadmin} -l add --random-key --use-defaults dummy@${R} || exit 1
+${kadmin} -l del dummy@${R} || exit 1
+${kadmin} -l get recovtest@${R} | grep 'Attributes: requires-pre-auth$' > /dev/null || exit 1
+
+# -- foo
+ipds=
+ipdm=
+kdcpid=
+
+> iprop-stats
+> iprop-stats2
+rm -f iprop-slave-status iprop-slave-status2
+
+ipropd_slave2=$ipropd_slave
+ipropd_master2=$ipropd_master
+ipropd_slave="${ipropd_slave} --status-file=iprop-slave-status --port=$ipropport"
+ipropd_slave="${ipropd_slave} --hostname=slave.test.h5l.se -k ${keytab}"
+ipropd_slave="${ipropd_slave} --detach localhost"
+ipropd_master="${ipropd_master} --hostname=localhost -k ${keytab}"
+ipropd_master="${ipropd_master} --port=$ipropport"
+ipropd_master="${ipropd_master} --database=${objdir}/current-db --detach"
+
+ipropd_slave2="${ipropd_slave2} --status-file=iprop-slave-status2 --port=$ipropport2"
+ipropd_slave2="${ipropd_slave2} --hostname=slave.test.h5l.se -k ${keytab}"
+ipropd_slave2="${ipropd_slave2} --pidfile-basename=ipropd-slave2"
+ipropd_slave2="${ipropd_slave2} --detach localhost"
+ipropd_master2="${ipropd_master2} --hostname=localhost -k ${keytab}"
+ipropd_master2="${ipropd_master2} --port=$ipropport2"
+ipropd_master2="${ipropd_master2} --pidfile-basename=ipropd-master2"
+ipropd_master2="${ipropd_master2} --database=${objdir}/current-db.slave --detach"
+
+cleanup() {
+ echo 'killing ipropd s + m + kdc'
+ test -n "$ipdm" && kill -9 $ipdm >/dev/null 2>/dev/null
+ test -n "$ipdm2" && kill -9 $ipdm2 >/dev/null 2>/dev/null
+ test -n "$ipds" && kill -9 $ipds >/dev/null 2>/dev/null
+ test -n "$ipds2" && kill -9 $ipds2 >/dev/null 2>/dev/null
+ test -n "$kdcpid" && kill -9 $kdcpid >/dev/null 2>/dev/null
+ tail messages.log
+ tail iprop-stats
+ exit 1
+}
+trap cleanup EXIT
+
+echo Starting kdc ; > messages.log
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+echo "starting master" ; > messages.log
+env ${HEIM_MALLOC_DEBUG} \
+${ipropd_master} || { echo "ipropd-master failed to start"; exit 1; }
+ipdm=`getpid ipropd-master`
+
+echo "starting slave" ; > messages.log
+env ${HEIM_MALLOC_DEBUG} \
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${ipropd_slave} || { echo "ipropd-slave failed to start"; exit 1; }
+ipds=`getpid ipropd-slave`
+sh ${wait_kdc} ipropd-slave messages.log 'slave status change: up-to-date' || exit 1
+get_iprop_ver || exit 1
+
+echo "checking slave is up"
+${EGREP} 'iprop/slave.test.h5l.se@TEST.H5L.SE.*Up' iprop-stats >/dev/null || exit 1
+${EGREP} 'up-to-date with version' iprop-slave-status >/dev/null || { echo "slave to up to date" ; cat iprop-slave-status ; exit 1; }
+
+# Also setup a second master on the slave, then a second slave to pull from the
+# second master.
+echo "starting master2" ; > messages.log
+env ${HEIM_MALLOC_DEBUG} \
+KRB5_CONFIG="${objdir}/krb5-master2.conf" \
+${ipropd_master2} || { echo "second ipropd-master failed to start"; exit 1; }
+ipdm2=`getpid ipropd-master2`
+
+echo "starting slave2" ; > messages.log
+env ${HEIM_MALLOC_DEBUG} \
+KRB5_CONFIG="${objdir}/krb5-slave2.conf" \
+${ipropd_slave2} || { echo "ipropd-slave failed to start"; exit 1; }
+ipds2=`getpid ipropd-slave2`
+sh ${wait_kdc} ipropd-slave messages2.log 'slave status change: up-to-date' || exit 1
+wait_for "Slave sees new host" get_iprop_ver2 0 || exit 1
+
+# ----------------- checking: pushing lives changes
+
+slave_get() { KRB5_CONFIG="${objdir}/krb5-slave.conf" ${kadmin} -l get "$@"; }
+slave_check_exists() {
+ # Creation with a random key is not atomic, there are at present
+ # 3 log entries to create a random key principal, the entry is
+ # "invalid" for the first two of these. We wait for the entry to
+ # exist and not be invalid
+ #
+ attrs=`slave_get -o attributes "$@" 2>/dev/null` || return 1
+ echo $attrs | egrep 'Attributes:' | egrep -v invalid >/dev/null || return 1
+ get_iprop_ver 0
+}
+
+echo "Add host"
+${kadmin} -l add --random-key --use-defaults host/foo@${R} || exit 1
+wait_for_slave
+wait_for "Slave sees new host" slave_check_exists "host/foo@${R}"
+
+echo "Rollover host keys"
+${kadmin} -l cpw -r --keepold host/foo@${R} || exit 1
+${kadmin} -l cpw -r --keepold host/foo@${R} || exit 1
+${kadmin} -l cpw -r --keepold host/foo@${R} || exit 1
+wait_for_slave 3
+slave_get host/foo@${R} | \
+ ${EGREP} Keytypes: | cut -d: -f2 | tr ' ' '
+' | sed 's/^.*[[]\(.*\)[]].*$/\1/' | grep '[0-9]' | sort -nu | tr -d '
+' | ${EGREP} 1234 > /dev/null || exit 1
+
+wait_for_slave2 4
+
+echo "Delete 3DES keys"
+${kadmin} -l del_enctype host/foo@${R} des3-cbc-sha1
+wait_for_slave
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${kadmin} -l get host/foo@${R} | \
+ ${EGREP} Keytypes: | cut -d: -f2 | tr ' ' '
+' | sed 's/^.*[[]\(.*\)[]].*$/\1/' | grep '[0-9]' | sort -nu | tr -d '
+' | ${EGREP} 1234 > /dev/null || exit 1
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${kadmin} -l get host/foo@${R} | \
+ ${EGREP} 'Keytypes:.*des3-cbc-sha1' > /dev/null && exit 1
+
+echo "Change policy host"
+${kadmin} -l modify --policy=default host/foo@${R} || exit 1
+wait_for_slave
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${kadmin} -l get host/foo@${R} > /dev/null 2>/dev/null || exit 1
+
+echo "Rename host"
+${kadmin} -l rename host/foo@${R} host/bar@${R} || exit 1
+wait_for_slave
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${kadmin} -l get host/foo@${R} > /dev/null 2>/dev/null && exit 1
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${kadmin} -l get host/bar@${R} > /dev/null || exit 1
+
+wait_for_slave2 3
+
+echo "Delete host"
+${kadmin} -l delete host/bar@${R} || exit 1
+wait_for_slave
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${kadmin} -l get host/bar@${R} > /dev/null 2>/dev/null && exit 1
+
+# See note below in LMDB sanity checking
+echo "Re-add host"
+${kadmin} -l add --random-key --use-defaults host/foo@${R} || exit 1
+${kadmin} -l add --random-key --use-defaults host/bar@${R} || exit 1
+wait_for_slave 2
+wait_for "Slave sees re-added host" slave_check_exists "host/bar@${R}"
+
+wait_for_slave2 3
+
+echo "kill slave and remove log and database"
+> iprop-stats
+sh ${leaks_kill} ipropd-slave $ipds || exit 1
+rm -f iprop-slave-status
+
+wait_for_slave_down
+${EGREP} 'iprop/slave.test.h5l.se@TEST.H5L.SE.*Down' iprop-stats >/dev/null || exit 1
+
+# ----------------- checking: slave is missing changes while down
+
+rm current.slave.log current-db.slave* || exit 1
+
+echo "doing changes while slave is down"
+${kadmin} -l cpw --random-password user@${R} > /dev/null || exit 1
+${kadmin} -l cpw --random-password user@${R} > /dev/null || exit 1
+
+echo "Making a copy of the master log file"
+cp ${objdir}/current.log ${objdir}/current.log.tmp
+
+# ----------------- checking: checking that master and slaves resyncs
+
+echo "starting slave again" ; > messages.log
+> iprop-stats
+env ${HEIM_MALLOC_DEBUG} \
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${ipropd_slave} || { echo "ipropd-slave failed to start"; exit 1; }
+ipds=`getpid ipropd-slave`
+
+echo "checking slave is up again"
+wait_for "slave to start and connect to master" \
+ ${EGREP} 'iprop/slave.test.h5l.se@TEST.H5L.SE.*Up' iprop-stats >/dev/null
+wait_for_slave 2
+wait_for_slave2 2
+${EGREP} 'up-to-date with version' iprop-slave-status >/dev/null || { echo "slave not up to date" ; cat iprop-slave-status ; exit 1; }
+echo "checking for replay problems"
+${EGREP} 'Entry already exists in database' messages.log && exit 1
+
+echo "compare versions on master and slave logs (no lock)"
+KRB5_CONFIG=${objdir}/krb5-slave.conf \
+${iprop_log} last-version -n > slave-last.tmp
+${iprop_log} last-version -n > master-last.tmp
+cmp master-last.tmp slave-last.tmp || exit 1
+
+echo "kill slave and remove log and database"
+sh ${leaks_kill} ipropd-slave $ipds || exit 1
+wait_for_slave_down
+
+rm current.slave.log current-db.slave* || exit 1
+> iprop-stats
+rm -f iprop-slave-status
+echo "starting slave" ; > messages.log
+env ${HEIM_MALLOC_DEBUG} \
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${ipropd_slave} || { echo "ipropd-slave failed to start"; exit 1; }
+ipds=`getpid ipropd-slave`
+wait_for_slave 0
+
+echo "checking slave is up again"
+wait_for "slave to start and connect to master" \
+ ${EGREP} 'iprop/slave.test.h5l.se@TEST.H5L.SE.*Up' iprop-stats >/dev/null
+${EGREP} 'up-to-date with version' iprop-slave-status >/dev/null || { echo "slave not up to date" ; cat iprop-slave-status ; exit 1; }
+echo "checking for replay problems"
+${EGREP} 'Entry already exists in database' messages.log && exit 1
+
+# ----------------- checking: checking live truncation of master log
+
+${kadmin} -l cpw --random-password user@${R} > /dev/null || exit 1
+wait_for_slave
+wait_for_slave2
+
+echo "live truncate on master log"
+${iprop_log} truncate -K 5 || exit 1
+wait_for_slave 0
+
+echo "Killing master and slave"
+sh ${leaks_kill} ipropd-master $ipdm || exit 1
+sh ${leaks_kill} ipropd-slave $ipds || exit 1
+
+rm -f iprop-slave-status
+
+wait_for_slave_down
+wait_for_master_down
+
+echo "compare versions on master and slave logs"
+KRB5_CONFIG=${objdir}/krb5-slave.conf \
+${iprop_log} last-version > slave-last.tmp
+${iprop_log} last-version > master-last.tmp
+cmp master-last.tmp slave-last.tmp || exit 1
+
+# ----------------- checking: master going backward
+> iprop-stats
+> messages.log
+
+echo "Going back to old version of the master log file"
+cp ${objdir}/current.log.tmp ${objdir}/current.log
+
+echo "starting master" ; > messages.log
+env ${HEIM_MALLOC_DEBUG} \
+${ipropd_master} || { echo "ipropd-master failed to start"; exit 1; }
+ipdm=`getpid ipropd-master`
+
+echo "starting slave" ; > messages.log
+env ${HEIM_MALLOC_DEBUG} \
+KRB5_CONFIG="${objdir}/krb5-slave.conf" \
+${ipropd_slave} || { echo "ipropd-slave failed to start"; exit 1; }
+ipds=`getpid ipropd-slave`
+wait_for_slave -1
+
+echo "checking slave is up again"
+wait_for "slave to start and connect to master" \
+ ${EGREP} 'iprop/slave.test.h5l.se@TEST.H5L.SE.*Up' iprop-stats >/dev/null
+${EGREP} 'up-to-date with version' iprop-slave-status >/dev/null || { echo "slave to up to date" ; cat iprop-slave-status ; exit 1; }
+echo "checking for replay problems"
+${EGREP} 'Entry already exists in database' messages.log && exit 1
+
+echo "pushing one change"
+${kadmin} -l cpw --random-password user@${R} > /dev/null || exit 1
+wait_for_slave
+wait_for_slave2 0
+
+echo "Killing master"
+sh ${leaks_kill} ipropd-master $ipdm || exit 1
+
+wait_for_master_down
+
+wait_for "slave to disconnect" \
+ ${EGREP} 'disconnected' iprop-slave-status >/dev/null
+
+if ! tail -30 messages.log | grep 'disconnected for server' > /dev/null; then
+ echo "client didnt disconnect"
+ exit 1
+fi
+
+echo "probing for slave pid"
+kill -0 ${ipds} || { echo "slave no longer there"; exit 1; }
+
+> messages.log
+
+echo "Staring master again" ; > messages.log
+env ${HEIM_MALLOC_DEBUG} \
+${ipropd_master} || { echo "ipropd-master failed to start"; exit 1; }
+ipdm=`getpid ipropd-master`
+
+echo "probing for slave pid"
+kill -0 ${ipds} || { echo "slave no longer there"; exit 1; }
+
+
+echo "pushing one change"
+${kadmin} -l cpw --random-password user@${R} > /dev/null || exit 1
+wait_for_slave
+wait_for_slave2
+
+echo "shutting down all services"
+
+leaked=false
+sh ${leaks_kill} kdc $kdcpid || leaked=true
+sh ${leaks_kill} ipropd-master $ipdm || leaked=true
+sh ${leaks_kill} ipropd-slave $ipds || leaked=true
+sh ${leaks_kill} ipropd-master $ipdm2 || leaked=true
+sh ${leaks_kill} ipropd-slave $ipds2 || leaked=true
+rm -f iprop-slave-status
+trap "" EXIT
+$leaked && exit 1
+
+echo "compare versions on master and slave logs"
+KRB5_CONFIG=${objdir}/krb5-slave.conf \
+${iprop_log} last-version > slave-last.tmp
+${iprop_log} last-version > master-last.tmp
+cmp master-last.tmp slave-last.tmp || exit 1
+
+if [ "$db_type" = lmdb ] && type mdb_stat > /dev/null 2>&1; then
+ # Sanity check that we have the same number of principals at the HDB
+ # and LMDB levels.
+ #
+ # We should also do this for the sqlite backend, but that would
+ # require a sqlite3(1) shell that is capable of opening our HDB
+ # files.
+ echo "checking that principals in DB == entries in LMDB"
+ # Add one to match lmdb overhead
+ princs=`(echo; ${kadmin} -l list '*') | wc -l`
+ entries=`mdb_stat -n current-db.mdb | grep 'Entries:' | awk '{print $2}'`
+ [ "$princs" -eq "$entries" ] || exit 1
+fi
+
+exit 0
diff --git a/third_party/heimdal/tests/kdc/check-kadmin.in b/third_party/heimdal/tests/kdc/check-kadmin.in
new file mode 100644
index 0000000..339868b
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-kadmin.in
@@ -0,0 +1,456 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+srcdir="@srcdir@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+R2=TEST2.H5L.SE
+
+port=@port@
+admport=@admport@
+
+cache="FILE:${objdir}/cache.krb5"
+
+kadmin="${kadmin} -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+kadmind="${kadmind} -p $admport"
+
+server=host/datan.test.h5l.se
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+
+foopassword="fooLongPasswordYo123;"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+rm -f messages.log
+
+> messages.log
+
+echo Creating database
+${kadmin} -l \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} -l add -p "$foopassword" --use-defaults foo/admin@${R} || exit 1
+${kadmin} -l add -p "$foopassword" --use-defaults bar@${R} || exit 1
+${kadmin} -l add -p "$foopassword" --use-defaults baz@${R} || exit 1
+${kadmin} -l add -p "$foopassword" --use-defaults bez@${R} || exit 1
+${kadmin} -l add -p "$foopassword" --use-defaults fez@${R} || exit 1
+${kadmin} -l add -p "$foopassword" --use-defaults hasalias@${R} || exit 1
+${kadmin} -l add -p "$foopassword" --use-defaults pkinit@${R} || exit 1
+${kadmin} -l modify --pkinit-acl="CN=baz,DC=test,DC=h5l,DC=se" pkinit@${R} || exit 1
+${kadmin} -l add -p "$foopassword" --use-defaults prune@${R} || exit 1
+${kadmin} -l cpw --keepold --random-key prune@${R} || exit 1
+${kadmin} -l cpw --keepold --random-key prune@${R} || exit 1
+${kadmin} -l add -p "$foopassword" --use-defaults pruneall@${R} || exit 1
+${kadmin} -l cpw --pruneall --random-key pruneall@${R} || exit 1
+${kadmin} -l cpw --pruneall --random-key pruneall@${R} || exit 1
+
+echo "$foopassword" > ${objdir}/foopassword
+
+echo Starting kdc ; > messages.log
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+echo Starting kadmind
+${kadmind} --detach --list-chunk-size=1 \
+ || { echo "kadmind failed to start"; cat messages.log; exit 1; }
+kadmpid=`getpid kadmind`
+
+trap "kill -9 ${kdcpid} ${kadmpid}" EXIT
+
+#----------------------------------
+echo "kinit (no admin); test mod --alias authorization"
+${kinit} --password-file=${objdir}/foopassword \
+ -S kadmin/admin@${R} hasalias@${R} || exit 1
+
+# Check that one non-permitted alias -> failure
+env KRB5CCNAME=${cache} \
+${kadmin} -p hasalias@${R} modify --alias=goodalias1@${R} --alias=badalias@${R} hasalias@${R} &&
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+
+# Check that all permitted aliases -> success
+env KRB5CCNAME=${cache} \
+${kadmin} -p hasalias@${R} modify --alias=goodalias1@${R} --alias=goodalias2@${R} hasalias@${R} ||
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+
+# Check that we can drop aliases
+env KRB5CCNAME=${cache} \
+${kadmin} -p hasalias@${R} modify --alias=goodalias3@${R} hasalias@${R} ||
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+${kadmin} -l get hasalias@${R} | grep Aliases: > kadmin.tmp
+read junk aliases < kadmin.tmp
+rm kadmin.tmp
+[ "$aliases" != "goodalias3@${R}" ] && { echo "kadmind failed $?"; cat messages.log ; exit 1; }
+
+env KRB5CCNAME=${cache} \
+${kadmin} -p hasalias@${R} modify --alias=goodalias1@${R} --alias=goodalias2@${R} --alias=goodalias3@${R} hasalias@${R} ||
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+${kadmin} -l get hasalias@${R} | grep Aliases: > kadmin.tmp
+read junk aliases < kadmin.tmp
+rm kadmin.tmp
+[ "$aliases" != "goodalias1@${R} goodalias2@${R} goodalias3@${R}" ] && { echo "FOO failed $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kinit (no admin)"
+${kinit} --password-file=${objdir}/foopassword \
+ -S kadmin/admin@${R} bar@${R} || exit 1
+echo "kadmin"
+env KRB5CCNAME=${cache} \
+${kadmin} -p bar@${R} add -p "$foopassword" --use-defaults kaka2@${R} ||
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+
+${kadmin} -l get kaka2@${R} > /dev/null ||
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kinit (no admin)"
+${kinit} --password-file=${objdir}/foopassword \
+ -S kadmin/admin@${R} baz@${R} || exit 1
+echo "kadmin globacl"
+env KRB5CCNAME=${cache} \
+${kadmin} -p baz@${R} get bar@${R} > /dev/null ||
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kinit (no admin)"
+${kinit} --password-file=${objdir}/foopassword \
+ -S kadmin/admin@${R} baz@${R} || exit 1
+echo "kadmin globacl, negative"
+env KRB5CCNAME=${cache} \
+${kadmin} -p baz@${R} passwd -p "$foopassword" bar@${R} > /dev/null 2>/dev/null &&
+ { echo "kadmin succesded $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kinit (no admin)"
+${kinit} --password-file=${objdir}/foopassword \
+ -S kadmin/admin@${R} baz@${R} || exit 1
+echo "kadmin globacl"
+env KRB5CCNAME=${cache} \
+${kadmin} -p baz@${R} get bar@${R} > /dev/null ||
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kinit (no admin)"
+${kinit} --password-file=${objdir}/foopassword \
+ -S kadmin/admin@${R} bez@${R} || exit 1
+echo "kadmin globacl, negative"
+env KRB5CCNAME=${cache} \
+${kadmin} -p bez@${R} passwd -p "$foopassword" bar@${R} > /dev/null 2>/dev/null &&
+ { echo "kadmin succesded $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kinit (no admin)"
+${kinit} --password-file=${objdir}/foopassword \
+ -S kadmin/admin@${R} fez@${R} || exit 1
+echo "kadmin globacl"
+env KRB5CCNAME=${cache} \
+${kadmin} -p fez@${R} get bar@${R} > /dev/null ||
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kinit (no admin)"
+${kinit} --password-file=${objdir}/foopassword \
+ -S kadmin/admin@${R} fez@${R} || exit 1
+echo "kadmin globacl, negative"
+env KRB5CCNAME=${cache} \
+${kadmin} -p fez@${R} passwd -p "$foopassword" bar@${R} > /dev/null 2>/dev/null &&
+ { echo "kadmin succesded $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kinit (admin)"
+${kinit} --password-file=${objdir}/foopassword \
+ -S kadmin/admin@${R} foo/admin@${R} || exit 1
+
+echo "kadmin"
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} add -p "$foopassword" --use-defaults kaka@${R} ||
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+
+echo "kadmin"
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} add -p abc --use-defaults kaka@${R} &&
+ { echo "kadmin succeeded $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kadmin get doesnotexists"
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} get -s doesnotexists@${R} \
+ > /dev/null 2>kadmin.tmp && \
+ { echo "kadmin passed"; cat messages.log ; exit 1; }
+
+# evil hack to support libtool
+sed 's/lt-kadmin:/kadmin:/' < kadmin.tmp > kadmin2.tmp
+mv kadmin2.tmp kadmin.tmp
+
+# If client tried IPv6, but service only listened on IPv4
+grep -v ': connect' kadmin.tmp > kadmin2.tmp
+mv kadmin2.tmp kadmin.tmp
+
+diff kadmin.tmp ${srcdir}/donotexists.txt || \
+ { echo "wrong response"; exit 1;}
+
+#----------------------------------
+echo "kadmin get pkinit-acl"
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} get -o pkinit-acl pkinit@${R} \
+ > /dev/null || \
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kadmin get -o principal"
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} get -o principal bar@${R} \
+ > kadmin.tmp 2>&1 || \
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+if test "`cat kadmin.tmp`" != "Principal: bar@TEST.H5L.SE" ; then
+ cat kadmin.tmp ; cat messages.log ; exit 1 ;
+fi
+
+
+#----------------------------------
+echo "kadmin get -o kvno"
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} get -o kvno bar@${R} \
+ > kadmin.tmp 2>&1 || \
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+if test "`cat kadmin.tmp`" != "Kvno: 1" ; then
+ cat kadmin.tmp ; cat messages.log ; exit 1 ;
+fi
+
+
+#----------------------------------
+echo "kadmin get -o princ_expire_time"
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} get -o princ_expire_time bar@${R} \
+ > kadmin.tmp 2>&1 || \
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+if test "`cat kadmin.tmp`" != "Principal expires: never" ; then
+ cat kadmin.tmp ; cat messages.log ; exit 1 ;
+fi
+
+#----------------------------------
+echo "kadmin get -s -o attributes"
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} get -s -o attributes bar@${R} \
+ > kadmin.tmp || \
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+if test "`cat kadmin.tmp`" != "Attributes" ; then
+ cat kadmin.tmp ; cat messages.log ; exit 1 ;
+fi
+
+#----------------------------------
+echo "kadmin prune"
+env KRB5CCNAME=${cache} \
+${kadmin} prune --kvno=2 prune@${R} \
+ > kadmin.tmp 2>&1 || \
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+env KRB5CCNAME=${cache} \
+${kadmin} get prune@${R} \
+ > kadmin.tmp 2>&1 || \
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+cat kadmin.tmp | ${EGREP} Keytypes: | cut -d: -f2 | tr ' ' '
+' | sed 's/^.*[[]\(.*\)[]].*$/\1/' | grep '[0-9]' | sort -nu | tr -d '
+' | ${EGREP} '^13$' > /dev/null || \
+ { echo "kadmin prune failed $?"; cat messages.log ; exit 1; }
+
+#----------------------------------
+echo "kadmin pruneall"
+env KRB5CCNAME=${cache} \
+${kadmin} get pruneall@${R} \
+ > kadmin.tmp 2>&1 || \
+ { echo "kadmin failed $?"; cat messages.log ; exit 1; }
+cat kadmin.tmp | ${EGREP} Keytypes: | cut -d: -f2 | tr ' ' '
+' | sed 's/^.*[[]\(.*\)[]].*$/\1/' | grep '[0-9]' | sort -nu | tr -d '
+' | ${EGREP} '^3$' > /dev/null || \
+ { echo "kadmin pruneall failed $?"; cat messages.log ; exit 1; }
+
+env KRB5CCNAME=${cache} \
+ ${kadmin} -p foo/admin@${R} list --upto=3 '*' > kadmin.tmp
+[ `wc -l < kadmin.tmp` -eq 3 ] ||
+ { echo "kadmin list --upto 3 produced `wc -l < kadmin.tmp` results!"; exit 1; }
+
+#----------------------------------
+echo "kadmin get '*' (re-entrance)"; > messages.log
+${kadmin} -l get '*' > kadmin.tmp ||
+ { echo "failed to list principals"; cat messages.log ; exit 1; }
+> messages.log
+env KRB5CCNAME=${cache} \
+ ${kadmin} -p foo/admin@${R} get '*' > kadmin.tmp2 ||
+ { echo "failed to list principals"; cat messages.log ; exit 1; }
+diff -u kadmin.tmp kadmin.tmp2 ||
+ { echo "local and remote get all differ"; exit 1; }
+
+#----------------------------------
+# We have 20 principals in the DB. Test two chunks of 1 (since that's how we
+# started kadmind above.
+> messages.log
+echo "kadmin list all (chunk size 1)"
+# Check that list produces the same output locally and remote.
+env KRB5CCNAME=${cache} \
+ ${kadmin} -p foo/admin@${R} list '*' | sort > kadmin.tmp ||
+ { echo "failed to list principals"; cat messages.log ; exit 1; }
+${kadmin} -l list '*' | sort > kadmin.tmp2
+diff kadmin.tmp kadmin.tmp2 ||
+ { echo "failed to list all principals"; cat messages.log ; exit 1; }
+# kadmin dump does not use kadm5_iter_principals, so this is a good way to
+# double check the above results. This time we drop the realm part because
+# kadmin doesn't show us the realm for principals in the default realm.
+${kadmin} -l list '*' | cut -d'@' -f1 | sort > kadmin.tmp
+${kadmin} -l dump | cut -d'@' -f1 | sort > kadmin.tmp2
+diff kadmin.tmp kadmin.tmp2 ||
+ { echo "failed to list all principals (dump)"; cat messages.log ; exit 1; }
+${kadmin} -l > kadmin.tmp <<"EOF"
+list *
+get foo/admin
+EOF
+grep Attributes kadmin.tmp > /dev/null ||
+ { echo "failed to execute command after list"; cat messages.log ; exit 1; }
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} > kadmin.tmp <<"EOF"
+list *
+get foo/admin
+EOF
+grep Attributes kadmin.tmp > /dev/null ||
+ { echo "failed to execute command after list"; cat messages.log ; exit 1; }
+
+#----------------------------------
+# We have 20 principals in the DB. Test two chunks of 10.
+sh ${leaks_kill} kadmind $kadmpid || exit 1
+${kadmind} --list-chunk-size=10 --detach
+kadmpid=`getpid kadmind`
+
+> messages.log
+echo "kadmin list all (chunk size 10)"
+# Check that list produces the same output locally and remote.
+env KRB5CCNAME=${cache} \
+ ${kadmin} -p foo/admin@${R} list '*' | sort > kadmin.tmp ||
+ { echo "failed to list principals"; cat messages.log ; exit 1; }
+${kadmin} -l list '*' | sort > kadmin.tmp2
+diff kadmin.tmp kadmin.tmp2 ||
+ { echo "failed to list all principals"; cat messages.log ; exit 1; }
+# kadmin dump does not use kadm5_iter_principals, so this is a good way to
+# double check the above results. This time we drop the realm part because
+# kadmin doesn't show us the realm for principals in the default realm.
+${kadmin} -l list '*' | cut -d'@' -f1 | sort > kadmin.tmp
+${kadmin} -l dump | cut -d'@' -f1 | sort > kadmin.tmp2
+diff kadmin.tmp kadmin.tmp2 ||
+ { echo "failed to list all principals (dump)"; cat messages.log ; exit 1; }
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} > kadmin.tmp <<"EOF"
+list *
+get foo/admin
+EOF
+grep Attributes kadmin.tmp > /dev/null ||
+ { echo "failed to execute command after list"; cat messages.log ; exit 1; }
+
+#----------------------------------
+# We have 20 principals in the DB. Test one chunk of 50.
+sh ${leaks_kill} kadmind $kadmpid || exit 1
+${kadmind} --list-chunk-size=50 --detach
+kadmpid=`getpid kadmind`
+
+> messages.log
+echo "kadmin list all (chunk size 50)"
+# Check that list produces the same output locally and remote.
+env KRB5CCNAME=${cache} \
+ ${kadmin} -p foo/admin@${R} list '*' | sort > kadmin.tmp ||
+ { echo "failed to list principals"; cat messages.log ; exit 1; }
+${kadmin} -l list '*' | sort > kadmin.tmp2
+diff kadmin.tmp kadmin.tmp2 ||
+ { echo "failed to list all principals"; cat messages.log ; exit 1; }
+# kadmin dump does not use kadm5_iter_principals, so this is a good way to
+# double check the above results. This time we drop the realm part because
+# kadmin doesn't show us the realm for principals in the default realm.
+${kadmin} -l list '*' | cut -d'@' -f1 | sort > kadmin.tmp
+${kadmin} -l dump | cut -d'@' -f1 | sort > kadmin.tmp2
+diff kadmin.tmp kadmin.tmp2 ||
+ { echo "failed to list all principals (dump)"; cat messages.log ; exit 1; }
+env KRB5CCNAME=${cache} \
+${kadmin} -p foo/admin@${R} > kadmin.tmp <<"EOF"
+list *
+get foo/admin
+EOF
+grep Attributes kadmin.tmp > /dev/null ||
+ { echo "failed to execute command after list"; cat messages.log ; exit 1; }
+
+#----------------------------------
+# We have 20 principals in the DB. Test 3 chunks of up to 7.
+sh ${leaks_kill} kadmind $kadmpid || exit 1
+${kadmind} --list-chunk-size=7 --detach
+kadmpid=`getpid kadmind`
+
+> messages.log
+echo "kadmin list all (chunk size 7)"
+# Check that list produces the same output locally and remote.
+env KRB5CCNAME=${cache} \
+ ${kadmin} -p foo/admin@${R} list '*' | sort > kadmin.tmp ||
+ { echo "failed to list principals"; cat messages.log ; exit 1; }
+${kadmin} -l list '*' | sort > kadmin.tmp2
+diff kadmin.tmp kadmin.tmp2 ||
+ { echo "failed to list all principals"; cat messages.log ; exit 1; }
+# kadmin dump does not use kadm5_iter_principals, so this is a good way to
+# double check the above results. This time we drop the realm part because
+# kadmin doesn't show us the realm for principals in the default realm.
+${kadmin} -l list '*' | cut -d'@' -f1 | sort > kadmin.tmp
+${kadmin} -l dump | cut -d'@' -f1 | sort > kadmin.tmp2
+diff kadmin.tmp kadmin.tmp2 ||
+ { echo "failed to list all principals (dump)"; cat messages.log ; exit 1; }
+
+#----------------------------------
+
+echo "killing kdc (${kdcpid} ${kadmpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+sh ${leaks_kill} kadmind $kadmpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-kdc-weak.in b/third_party/heimdal/tests/kdc/check-kdc-weak.in
new file mode 100644
index 0000000..182f530
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-kdc-weak.in
@@ -0,0 +1,37 @@
+#!/bin/sh
+#
+# Copyright (c) 2009 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+objdir="@objdir@"
+
+exec ${top_builddir}/tests/kdc/check-kdc ${objdir}/krb5-weak.conf
diff --git a/third_party/heimdal/tests/kdc/check-kdc.in b/third_party/heimdal/tests/kdc/check-kdc.in
new file mode 100644
index 0000000..307312e
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-kdc.in
@@ -0,0 +1,1131 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+KRB5_CONFIG="${1-${objdir}/krb5.conf}"
+export KRB5_CONFIG
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+RH=TEST-HTTP.H5L.SE
+R2=TEST2.H5L.SE
+R3=TEST3.H5L.SE
+R4=TEST4.H5L.SE
+R5=SOME-REALM5.FR
+R6=SOME-REALM6.US
+R7=SOME-REALM7.UK
+R8=SOME-REALM8.UK
+
+H1=H1.$R
+H2=H2.$R
+H3=H3.$H2
+H4=H4.$H2
+
+r=`echo "$R" | tr '[A-Z]' '[a-z]'`
+h1=`echo "${H1}" | tr '[A-Z]' '[a-z]'`
+h2=`echo "${H2}" | tr '[A-Z]' '[a-z]'`
+h3=`echo "${H3}" | tr '[A-Z]' '[a-z]'`
+h4=`echo "${H4}" | tr '[A-Z]' '[a-z]'`
+
+port=@port@
+pwport=@pwport@
+
+kadmin5="${kadmin} -l -r $R5"
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+kpasswdd="${kpasswdd} --addresses=localhost -p $pwport"
+
+server=host/datan.test.h5l.se
+server2=host/computer.example.com
+server3=host/refer-me-out.test.h5l.se
+server4=host/no-auth-data-reqd.test.h5l.se
+server5=host/a-host.refer-all-out.test.h5l.se
+namespace=WELLKNOWN/HOSTBASED-NAMESPACE/_/refer-all-out.test.h5l.se
+serverip=host/10.11.12.13
+serveripname=host/ip.test.h5l.org
+serveripname2=host/10.11.12.14
+alias1=host/datan.example.com
+alias2=host/datan
+aliaskeytab=host/datan
+cache="FILE:${objdir}/cache.krb5"
+ocache="FILE:${objdir}/ocache.krb5"
+o2cache="FILE:${objdir}/o2cache.krb5"
+icache="FILE:${objdir}/icache.krb5"
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+ps="proxy-service@${R}"
+rps="restricted-proxy-service@${R}"
+aesenctype="aes256-cts-hmac-sha1-96"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist2="${klist} -c $o2cache"
+klist="${klist} -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kgetcred_imp="${kgetcred} -c $cache --out-cache=${ocache}"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+kimpersonate="${kimpersonate} -k ${keytab} --ccache=${ocache}"
+test_set_kvno0="${test_set_kvno0} -c $cache"
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R2} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R3} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R4} || exit 1
+
+${kadmin5} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R5} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R6} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R7} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R8} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${H1} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${H2} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${H3} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${H4} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${RH} || exit 1
+
+${kadmin} cpw -r krbtgt/${R}@${R} || exit 1
+${kadmin} cpw -r krbtgt/${R}@${R} || exit 1
+${kadmin} cpw -r krbtgt/${R}@${R} || exit 1
+${kadmin} cpw -r krbtgt/${R}@${R} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} add -p foo --use-defaults foo/host.${r}@${R} || exit 1
+${kadmin} add -p foo --use-defaults foo@${R2} || exit 1
+${kadmin} add -p foo --use-defaults foo@${R3} || exit 1
+${kadmin} add -p foo --use-defaults foo@${R4} || exit 1
+${kadmin5} add -p foo --use-defaults foo@${R5} || exit 1
+${kadmin} add -p foo --use-defaults foo@${R6} || exit 1
+${kadmin} add -p foo --use-defaults foo@${R7} || exit 1
+${kadmin} add -p foo --use-defaults foo@${R8} || exit 1
+${kadmin} add -p foo --use-defaults foo@${H1} || exit 1
+${kadmin} add -p foo --use-defaults foo/host.${h1}@${H1} || exit 1
+${kadmin} add -p foo --use-defaults foo@${H2} || exit 1
+${kadmin} add -p foo --use-defaults foo/host.${h2}@${H2} || exit 1
+${kadmin} add -p foo --use-defaults foo@${H3} || exit 1
+${kadmin} add -p foo --use-defaults foo/host.${h3}@${H3} || exit 1
+${kadmin} add -p foo --use-defaults foo@${H4} || exit 1
+${kadmin} add -p foo --use-defaults foo/host.${h4}@${H4} || exit 1
+${kadmin} add -p bar --use-defaults bar@${R} || exit 1
+${kadmin} add -p foo --use-defaults remove@${R} || exit 1
+${kadmin} add -p nop --use-defaults ${server}@${R} || exit 1
+${kadmin} cpw -p bla --keepold ${server}@${R} || exit 1
+${kadmin} cpw -p kaka --keepold ${server}@${R} || exit 1
+${kadmin} add -p kaka --use-defaults ${server}-des3@${R} || exit 1
+${kadmin} add -p kaka --use-defaults kt-des3@${R} || exit 1
+${kadmin} add -p kaka --use-defaults foo/des3-only@${R} || exit 1
+${kadmin} add -p kaka --use-defaults bar/des3-only@${R} || exit 1
+${kadmin} add -p kaka --use-defaults foo/aes-only@${R} || exit 1
+
+${kadmin} add -p sens --use-defaults --attributes=disallow-forwardable sensitive@${R} || exit 1
+${kadmin} add -p foo --use-defaults ${ps} || exit 1
+${kadmin} modify --attributes=+trusted-for-delegation ${ps} || exit 1
+${kadmin} modify --constrained-delegation=${server} ${ps} || exit 1
+${kadmin} ext -k ${keytab} ${server}@${R} || exit 1
+${kadmin} ext -k ${keytab} ${ps} || exit 1
+
+# Note: rps is not trusted-for-delegation
+${kadmin} add -p foo --use-defaults ${rps} || exit 1
+${kadmin} modify --constrained-delegation=${server} ${rps} || exit 1
+${kadmin} ext -k ${keytab} ${rps} || exit 1
+
+${kadmin} add -p kaka --use-defaults ${server2}@${R2} || exit 1
+${kadmin} ext -k ${keytab} ${server2}@${R2} || exit 1
+${kadmin} add -p foo --use-defaults WELLKNOWN/REFERRALS/TARGET@${R5} || exit 1
+${kadmin} add_alias WELLKNOWN/REFERRALS/TARGET@${R5} ${server3}@${R} || exit 1
+${kadmin5} add -p kaka --use-defaults ${server3}@${R5} || exit 1
+${kadmin5} ext -k ${keytab} ${server3}@${R5} || exit 1
+${kadmin} add_alias WELLKNOWN/REFERRALS/TARGET@${R5} ${namespace}@${R} || exit 1
+${kadmin5} add -p kaka --use-defaults ${server5}@${R5} || exit 1
+${kadmin5} ext -k ${keytab} ${server5}@${R5} || exit 1
+${kadmin} add -p kaka --use-defaults ${serverip}@${R} || exit 1
+${kadmin} ext -k ${keytab} ${serverip}@${R} || exit 1
+${kadmin} add -p kaka --use-defaults ${serveripname}@${R} || exit 1
+${kadmin} ext -k ${keytab} ${serveripname}@${R} || exit 1
+${kadmin} modify --alias=${serveripname2}@${R} ${serveripname}@${R}
+${kadmin} add -p foo --use-defaults remove2@${R2} || exit 1
+
+${kadmin} add -p nopac --use-defaults ${server4}@${R2} || exit 1
+${kadmin} modify --attributes=+no-auth-data-reqd ${server4}@${R2} || exit 1
+${kadmin} ext -k ${keytab} ${server4}@${R2} || exit 1
+
+${kadmin} add -p kaka --use-defaults ${alias1}@${R} || exit 1
+${kadmin} ext -k ${keytab} ${alias1}@${R} || exit 1
+${kadmin} modify --alias=${alias2}@${R} ${alias1}@${R}
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R2}@${R} || exit 1
+${kadmin} modify --attributes=+no-auth-data-reqd krbtgt/${R2}@${R} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R}@${R2} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R3}@${R2} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R2}@${R3} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R4}@${R2} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R2}@${R4} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R4}@${R3} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R3}@${R4} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R5}@${R} || exit 1
+${kadmin5} add -p cross2 --use-defaults krbtgt/${R}@${R5} || exit 1
+
+${kadmin5} add -p cross1 --use-defaults krbtgt/${R6}@${R5} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R5}@${R6} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R7}@${R6} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R6}@${R7} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R8}@${R6} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R6}@${R8} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${H1}@${R} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R}@${H1} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${H2}@${R} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R}@${H2} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${H3}@${H2} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${H2}@${H3} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${H3}@${H4} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${H4}@${H3} || exit 1
+
+${kadmin} add -p foo --use-defaults pw-expire@${R} || exit 1
+${kadmin} modify --pw-expiration-time=+1day pw-expire@${R} || exit 1
+
+${kadmin} add -p foo --use-defaults pw-expired@${R} || exit 1
+${kadmin} modify --pw-expiration-time=2012-06-12 pw-expired@${R} || exit 1
+
+${kadmin} add -p foo --use-defaults account-expired@${R} || exit 1
+${kadmin} modify --expiration-time=2012-06-12 account-expired@${R} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${RH} || exit 1
+
+echo "Check parser"
+${kadmin} add -p foo --use-defaults -- -p || exit 1
+${kadmin} delete -- -p || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+${kadmin} check ${R2} || exit 1
+${kadmin} check ${R3} || exit 1
+${kadmin} check ${R4} || exit 1
+${kadmin5} check ${R5} || exit 1
+${kadmin} check ${R6} || exit 1
+${kadmin} check ${R7} || exit 1
+${kadmin} check ${R8} || exit 1
+${kadmin} check ${H1} || exit 1
+${kadmin} check ${H2} || exit 1
+${kadmin} check ${H3} || exit 1
+${kadmin} check ${H4} || exit 1
+
+echo "Extracting enctypes"
+${ktutil} -k ${keytab} list > tempfile || exit 1
+${EGREP} -v '^FILE:' tempfile | ${EGREP} -v '^Vno' | ${EGREP} -v '^$' | \
+ ${EGREP} -v "$server" | # we did cpw for this one
+ awk '$1 !~ /1/ { exit 1 }' || exit 1
+${EGREP} -v '^FILE:' tempfile | ${EGREP} -v '^Vno' | ${EGREP} -v '^$' | \
+ ${EGREP} "$server" | head -1 |
+ awk '$1 !~ /3/ { exit 1 }' || exit 1
+
+
+${kadmin} get foo@${R} > tempfile || exit 1
+enctypes=`grep Keytypes: tempfile | sed 's/(pw-salt)//g' | sed 's/,//g' | sed 's/Keytypes://' | sed 's/\[[0-9]*\]//g'`
+
+enctype_sans_aes=`echo $enctypes | sed 's/aes[^ ]*//g'`
+enctype_sans_des3=`echo $enctypes | sed 's/des3-cbc-sha1//g'`
+
+echo "deleting all but des enctypes on kt-des3 in keytab"
+${kadmin} ext -k ${keytab} kt-des3@${R} || exit 1
+for a in ${enctype_sans_des3} ; do
+ ${ktutil} -k ${keytab} remove -p kt-des3@${R} -e $a
+done
+
+echo "checking globbing keys rules"
+${kadmin} get foo/des3-only@${R} > tempfile || exit 1
+enctypes=`grep Keytypes: tempfile | sed 's/(pw-salt)//g' | sed 's/,//g' | sed 's/Keytypes://' | sed 's/\[[0-9]*\]//g' | sed 's/ //g'`
+if [ X"$enctypes" != Xdes3-cbc-sha1 ] ; then
+ echo "des3 only is not only des3: $enctypes"
+ exit 1
+fi
+
+${kadmin} get foo/aes-only@${R} > tempfile || exit 1
+enctypes=`grep Keytypes: tempfile | sed 's/(pw-salt)//g' | sed 's/,//g' | sed 's/Keytypes://' | sed 's/\[[0-9]*\]//g' | sed 's/ //g'`
+if [ X"$enctypes" != Xaes256-cts-hmac-sha1-96 ] ; then
+ echo "aes only is not only aes: $enctypes"
+ exit 1
+fi
+
+
+echo foo > ${objdir}/foopassword
+echo notfoo > ${objdir}/notfoopassword
+
+echo Starting kdc ; > messages.log
+env MallocStackLogging=1 MallocStackLoggingNoCompact=1 MallocErrorAbort=1 MallocLogFile=${objdir}/malloc-log \
+${kdc} --detach --testing ||
+ { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+echo Starting kpasswdd; > messages.log
+env ${HEIM_MALLOC_DEBUG} ${kpasswdd} --detach ||
+ { echo "kpasswdd failed to start"; exit 1; }
+kpasswddpid=`getpid kpasswdd`
+
+
+trap "kill -9 ${kdcpid} ${kpasswddpid}; echo signal killing kdc kpasswdd; exit 1;" EXIT
+
+ec=0
+
+echo "Getting client initial tickets with wrong password"; > messages.log
+${kadmin} modify --attributes=+disallow-client ${server} || exit 1
+${kinit} --password-file=${objdir}/notfoopassword \
+ foo@${R} 2>kinit-log.tmp && \
+ { ec=1 ; eval "${testfailed}"; }
+grep 'Password incorrect' kinit-log.tmp > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Doing krbtgt key rollover"; > messages.log
+${kadmin} cpw -r --keepold krbtgt/${R}@${R} || exit 1
+echo "Getting tickets"; > messages.log
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Listing tickets"; > messages.log
+${klist} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${test_ap_req} ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client initial tickets (http transport)"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@${RH} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Testing capaths logic"
+${kinit} --password-file=${objdir}/foopassword \
+ -e ${aesenctype} -e ${aesenctype} \
+ foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting x-realm tickets with capaths for $R -> $R2"
+${kgetcred} foo@${R2} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R3"
+${kgetcred} foo@${R3} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R4"
+${kgetcred} foo@${R4} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R5"
+${kgetcred} foo@${R5} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R6"
+${kgetcred} foo@${R6} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R7"
+${kgetcred} foo@${R7} || { ec=1 ; eval "${testfailed}"; }
+echo "Should not get x-realm tickets with capaths for $R -> $R8"
+${kgetcred} foo@${R8} && { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Testing capaths logic (reverse order)"
+${kinit} --password-file=${objdir}/foopassword \
+ -e ${aesenctype} -e ${aesenctype} \
+ foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting x-realm tickets with capaths for $R -> $R4"
+${kgetcred} foo@${R4} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R3"
+${kgetcred} foo@${R3} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R2"
+${kgetcred} foo@${R2} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R7"
+${kgetcred} foo@${R7} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R6"
+${kgetcred} foo@${R6} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with capaths for $R -> $R5"
+${kgetcred} foo@${R5} || { ec=1 ; eval "${testfailed}"; }
+echo "Testing HDB referral entry"
+${kgetcred} --canonicalize ${server3}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Testing HDB namespace referral entry"
+${kgetcred} --canonicalize ${server5}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist}
+${kdestroy}
+
+echo "Testing hierarchical referral logic"
+${kinit} --password-file=${objdir}/foopassword \
+ -e ${aesenctype} -e ${aesenctype} \
+ foo@${H3} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting x-realm tickets with HDB referral alias for $R1 -> $R3"
+${kgetcred} --hostbased --canonicalize foo host.${h1} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with hierarchical referrals for $H3 -> $H1"
+${kgetcred} --hostbased --canonicalize foo host.${h1} || { ec=1 ; eval "${testfailed}"; }
+fgrep "cross-realm ${H3} -> ${H1} via [${H2}, ${R}]" messages.log > /dev/null || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with hierarchical referrals for $H3 -> $R"
+${kgetcred} --hostbased --canonicalize foo host.${r} || { ec=1 ; eval "${testfailed}"; }
+fgrep "cross-realm ${H3} -> ${R} via [${H2}]" messages.log > /dev/null || { ec=1 ; eval "${testfailed}"; }
+echo "Getting x-realm tickets with hierarchical referrals for $H3 -> $H2"
+${kgetcred} --hostbased --canonicalize foo host.${h2} || { ec=1 ; eval "${testfailed}"; }
+fgrep "cross-realm ${H3} -> ${H2}" messages.log > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Testing multi-hop [capaths] referral logic"
+${kinit} --password-file=${objdir}/foopassword \
+ -e ${aesenctype} -e ${aesenctype} \
+ foo@${H4} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting x-realm tickets with [capaths] referrals for $H4 -> $H1"
+${kgetcred} --hostbased --canonicalize foo/host.${h1}@${H4} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Testing forwardable/renewable flag copying in TGS-REQ"
+${kinit} -f --renewable -r 5d --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} -f | grep ${server} | grep FRA > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Testing strip of forwardable when the server is disallowed in TGS-REQ"
+${kgetcred} sensitive@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} -f | grep sensitive | grep FRA > /dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Specific enctype"; > messages.log
+${kinit} --password-file=${objdir}/foopassword \
+ -e ${aesenctype} -e ${aesenctype} \
+ foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+
+for a in $enctypes; do
+ echo "Getting client initial tickets ($a)"; > messages.log
+ ${kinit} --enctype=$a --password-file=${objdir}/foopassword foo@$R || { ec=1 ; eval "${testfailed}"; }
+ echo "Getting tickets"; > messages.log
+ ${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} ${server}@${R} ${keytab} ${cache} || { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy}
+done
+
+
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+for a in $enctypes; do
+ echo "Getting tickets ($a)"; > messages.log
+ ${kgetcred} -e $a ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy} --credential=${server}@${R}
+done
+${kdestroy}
+
+echo "Getting client initial tickets without PAC"; > messages.log
+${kinit} --no-request-pac --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+for a in $enctypes; do
+ echo "Getting tickets ($a)"; > messages.log
+ ${kgetcred} -e $a ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} ${server}@${R} ${keytab} ${cache} && \
+ { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} --no-verify-pac ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy} --credential=${server}@${R}
+done
+${kdestroy}
+
+echo "Getting client initial tickets with PAC"; > messages.log
+${kinit} --request-pac --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+for a in $enctypes; do
+ echo "Getting tickets for PAC-less service principal ($a)"; > messages.log
+ ${kgetcred} -e $a ${server4}@${R2} || { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} --verify-pac ${server4}@${R2} ${keytab} ${cache} && \
+ { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} --no-verify-pac ${server4}@${R2} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy} --credential=${server4}@${R2}
+done
+${kdestroy}
+
+echo "Getting client initial tickets with PAC"; > messages.log
+${kinit} --request-pac --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+for a in $enctypes; do
+ echo "Getting tickets for PAC-less service principal ($a)"; > messages.log
+ ${kgetcred} -e $a ${server4}@${R2} || { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} --verify-pac ${server4}@${R2} ${keytab} ${cache} && \
+ { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} --no-verify-pac ${server4}@${R2} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy} --credential=${server4}@${R2}
+done
+${kdestroy}
+
+echo "Getting client authenticated anonymous initial tickets"; > messages.log
+${kinit} -n --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+for a in $enctypes; do
+ echo "Getting tickets ($a)"; > messages.log
+ ${kgetcred} -e $a ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} --no-verify-pac ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} --verify-pac ${server}@${R} ${keytab} ${cache} && \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy} --credential=${server}@${R}
+done
+${kdestroy}
+
+echo "Getting client anonymous service tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+for a in $enctypes; do
+ echo "Getting tickets ($a)"; > messages.log
+ ${kgetcred} -n -e $a ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy} --credential=${server}@${R}
+done
+${kdestroy}
+
+echo "Getting client initial tickets for cross realm case (no-auth-data-reqd for ${R2})"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || { ec=1 ; eval "${testfailed}"; }
+for a in $enctypes; do
+ echo "Getting cross realm tickets ($a)"; > messages.log
+ ${kgetcred} -e $a ${server2}@${R2} || { ec=1 ; eval "${testfailed}"; }
+ echo " checking we we got back right ticket"
+ ${klist} | grep ${server2}@ > /dev/null || { ec=1 ; eval "${testfailed}"; }
+ echo " checking if ticket is useful"
+ ${test_ap_req} --no-verify-pac ${server2}@${R2} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} --verify-pac ${server2}@${R2} ${keytab} ${cache} && \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy} --credential=${server2}@${R2}
+done
+${kdestroy}
+
+echo "Getting client initial tickets for cross realm case (w/ PAC)"; > messages.log
+${kadmin} modify --attributes=-no-auth-data-reqd krbtgt/${R2}@${R} || exit 1
+${kinit} --password-file=${objdir}/foopassword foo@$R || { ec=1 ; eval "${testfailed}"; }
+for a in $enctypes; do
+ echo "Getting cross realm tickets ($a)"; > messages.log
+ ${kgetcred} -e $a ${server2}@${R2} || { ec=1 ; eval "${testfailed}"; }
+ echo " checking we we got back right ticket"
+ ${klist} | grep ${server2}@ > /dev/null || { ec=1 ; eval "${testfailed}"; }
+ echo " checking if ticket is useful"
+ ${test_ap_req} --verify-pac ${server2}@${R2} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy} --credential=${server2}@${R2}
+done
+${kdestroy}
+
+echo "Trying x-realm TGT with kvno 0 case";
+${kinit} --password-file=${objdir}/foopassword foo@$R ||
+ { ec=1 ; eval "${testfailed}"; }
+${test_set_kvno0} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting cross realm tickets"; > messages.log
+${kgetcred} krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; }
+${test_set_kvno0} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting service ticket"; > messages.log
+${kgetcred} ${server2}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying x-realm TGT with kvno 0 case with key rollover";
+${kinit} --password-file=${objdir}/foopassword foo@$R ||
+ { ec=1 ; eval "${testfailed}"; }
+${test_set_kvno0} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting cross realm tickets"; > messages.log
+${kgetcred} krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Rolling over cross realm keys"; > messages.log
+${kadmin} cpw -r --keepold krbtgt/${R}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kadmin} cpw -r --keepold krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kadmin} cpw -r --keepold krbtgt/${R}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${test_set_kvno0} || { ec=1 ; eval "${testfailed}"; }
+echo "Getting service ticket"; > messages.log
+echo "Start tracing kdc, then hit return"
+${kgetcred} ${server2}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying x-realm TGT with no kvno case";
+${kinit} --password-file=${objdir}/foopassword foo@$R ||
+ { ec=1 ; eval "${testfailed}"; }
+${test_set_kvno0} -n || { ec=1 ; eval "${testfailed}"; }
+echo "Getting cross realm tickets"; > messages.log
+${kgetcred} krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; }
+${test_set_kvno0} -n || { ec=1 ; eval "${testfailed}"; }
+echo "Getting service ticket"; > messages.log
+${kgetcred} ${server2}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying x-realm TGT with no kvno case with key rollover";
+${kinit} --password-file=${objdir}/foopassword foo@$R ||
+ { ec=1 ; eval "${testfailed}"; }
+${test_set_kvno0} -n || { ec=1 ; eval "${testfailed}"; }
+echo "Getting cross realm tickets"; > messages.log
+${kgetcred} krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Rolling over cross realm keys"; > messages.log
+${kadmin} cpw -r --keepold krbtgt/${R}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kadmin} cpw -r --keepold krbtgt/${R2}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kadmin} cpw -r --keepold krbtgt/${R}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${test_set_kvno0} -n || { ec=1 ; eval "${testfailed}"; }
+echo "Getting service ticket"; > messages.log
+echo "Start tracing kdc, then hit return"
+${kgetcred} ${server2}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "try all permutations"; > messages.log
+for a in $enctypes; do
+ echo "Getting client initial tickets ($a)"; > messages.log
+ ${kinit} --enctype=$a --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+ for b in $enctypes; do
+ echo "Getting tickets ($a -> $b)"; > messages.log
+ ${kgetcred} -e $b ${server}@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy} --credential=${server}@${R}
+ done
+ ${kdestroy}
+done
+
+echo "Getting client initial tickets ip based name"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || { ec=1 ; eval "${testfailed}"; }
+echo "Getting ip based name tickets"; > messages.log
+${kgetcred} ${serverip}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo " checking we we got back right ticket"
+${klist} | grep ${serverip}@ > /dev/null || { ec=1 ; eval "${testfailed}"; }
+echo " checking if ticket is useful"
+${test_ap_req} ${serverip}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client initial tickets ip based name (alias)"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || { ec=1 ; eval "${testfailed}"; }
+for a in ${serveripname} ${serveripname2} ; do
+ echo "Getting ip based name tickets (alias) $a"; > messages.log
+ ${kgetcred} ${a}@${R} || { ec=1 ; eval "${testfailed}"; }
+ echo " checking we we got back right ticket"
+ ${klist} | grep ${a}@ > /dev/null || { ec=1 ; eval "${testfailed}"; }
+ echo " checking if ticket is useful"
+ ${test_ap_req} --server-any ${a}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+done
+${kdestroy}
+
+echo "Getting server initial tickets"; > messages.log
+${kinit} --keytab=${keytab} ${server}@$R && { ec=1 ; eval "${testfailed}"; }
+${kadmin} modify --attributes=-disallow-client ${server} || exit 1
+${kinit} --keytab=${keytab} ${server}@$R || { ec=1 ; eval "${testfailed}"; }
+echo "Listing tickets"; > messages.log
+${klist} | grep "Principal: ${server}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting key for key that are a subset in keytab compared to kdb"
+${kinit} --keytab=${keytab} kt-des3@${R}
+${klist} | grep "Principal: kt-des3" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "initial tickets for deleted user test case"; > messages.log
+${kinit} --password-file=${objdir}/foopassword remove@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+${kadmin} delete remove@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "try getting ticket with deleted user"; > messages.log
+${kgetcred} ${server}@${R} 2> /dev/null && { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "cross realm case (deleted user)"; > messages.log
+${kinit} --password-file=${objdir}/foopassword remove2@$R2 || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} krbtgt/${R}@${R2} 2> /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kadmin} delete remove2@${R2} || exit 1
+${kgetcred} ${server}@${R} 2> /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "rename user"; > messages.log
+${kadmin} add -p foo --use-defaults rename@${R} || exit 1
+${kinit} --password-file=${objdir}/foopassword rename@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kadmin} rename rename@${R} rename2@${R} || exit 1
+${kinit} --password-file=${objdir}/foopassword rename2@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+${kadmin} delete rename2@${R} || exit 1
+
+echo "rename user to another realm"; > messages.log
+${kadmin} add -p foo --use-defaults rename@${R} || exit 1
+${kinit} --password-file=${objdir}/foopassword rename@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kadmin} rename rename@${R} rename@${R2} || exit 1
+${kinit} --password-file=${objdir}/foopassword rename@${R2} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+${kadmin} delete rename@${R2} || exit 1
+
+echo deleting all but aes enctypes on krbtgt
+${kadmin} del_enctype krbtgt/${R}@${R} ${enctype_sans_aes} || exit 1
+
+echo deleting all but des enctypes on server-des3
+${kadmin} del_enctype ${server}-des3@${R} ${enctype_sans_des3} || exit 1
+${kadmin} ext -k ${keytab} ${server}-des3@${R} || exit 1
+
+echo "try all permutations (only aes)"; > messages.log
+for a in $enctypes; do
+ echo "Getting client initial tickets ($a)"; > messages.log
+ ${kinit} --enctype=$a --password-file=${objdir}/foopassword foo@${R} ||\
+ { ec=1 ; eval "${testfailed}"; }
+ for b in $enctypes; do
+ echo "Getting tickets ($a -> $b)"; > messages.log
+ ${kgetcred} -e $b ${server}@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+ echo "Getting tickets ($a -> $b) (server des3 only)"; > messages.log
+ ${kgetcred} ${server}-des3@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${test_ap_req} ${server}-des3@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+ ${kdestroy} --credential=${server}@${R}
+ ${kdestroy} --credential=${server}-des3@${R}
+ done
+ ${kdestroy}
+done
+
+echo deleting all enctypes on krbtgt
+${kadmin} del_enctype krbtgt/${R}@${R} aes256-cts-hmac-sha1-96 || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "try initial ticket w/o and keys on krbtgt"
+${kinit} --password-file=${objdir}/foopassword foo@${R} 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+echo "adding random aes key"
+${kadmin} add_enctype -r krbtgt/${R}@${R} aes256-cts-hmac-sha1-96 || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "try initial ticket with random aes key on krbtgt"
+${kinit} --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+rsa=yes
+ecdsa=yes
+pkinit=no
+if ${hxtool} info | grep 'rsa: hx509 null RSA' > /dev/null ; then
+ rsa=no
+fi
+if ${hxtool} info | grep 'rand: not available' > /dev/null ; then
+ rsa=no
+fi
+if ${kinit} --help 2>&1 | grep "CA certificates" > /dev/null; then
+ pkinit=yes
+fi
+
+if ${hxtool} info | grep 'ecdsa: hcrypto null' > /dev/null ; then
+ ecdsa=no
+fi
+
+
+# If we support pkinit and have RSA, lets try that
+if test "$pkinit" = yes -a "$rsa" = yes ; then
+
+ echo "try anonymous pkinit"; > messages.log
+ ${kinit} --renewable -n @${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${kinit} --renew || { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy}
+
+ for type in "" "--pk-use-enckey"; do
+ echo "Trying pk-init (principal in certificate) $type"; > messages.log
+ ${kinit} $type -C FILE:${hx509_data}/pkinit.crt,${hx509_data}/pkinit.key bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy}
+
+ echo "Trying pk-init (principal in pki-mapping) $type"; > messages.log
+ ${kinit} $type -C FILE:${hx509_data}/pkinit.crt,${hx509_data}/pkinit.key foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy}
+
+ echo "Trying pk-init (password protected key) $type"; > messages.log
+ ${kinit} $type -C FILE:${hx509_data}/pkinit.crt,${hx509_data}/pkinit-pw.key --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kgetcred} ${server}@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy}
+
+ echo "Trying pk-init (proxy cert) $type"; > messages.log
+ ${kinit} $type -C FILE:${hx509_data}/pkinit-proxy-chain.crt,${hx509_data}/pkinit-proxy.key foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy}
+
+ done
+
+ if test "$ecdsa" = yes > /dev/null ; then
+ echo "Trying pk-init (ec certificate)"
+ > messages.log
+ ${kinit} -C FILE:${hx509_data}/pkinit-ec.crt,${hx509_data}/pkinit-ec.key bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy}
+ grep 'PKINIT using ecdh' messages.log > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+ fi
+
+else
+ echo "no pkinit (pkinit: $pkinit, rsa: $rsa)"; > messages.log
+fi
+
+echo "test impersonate using rc4 based tgt"; > messages.log
+${kinit} -e arcfour-hmac-md5 --forwardable --password-file=${objdir}/foopassword ${ps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred_imp} --impersonate=bar@${R} ${ps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${test_ap_req} ${ps} ${keytab} ${ocache} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "tickets for impersonate test case"; > messages.log
+${kinit} --forwardable --password-file=${objdir}/foopassword ${ps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred_imp} --impersonate=bar@${R} ${ps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${test_ap_req} ${ps} ${keytab} ${ocache} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo " negative check"
+${kgetcred_imp} --impersonate=bar@${R} foo@${R} 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test impersonate unknown client"; > messages.log
+${kgetcred_imp} --forward --impersonate=unknown@${R} ${ps} && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test impersonate account-expired client"; > messages.log
+${kgetcred_imp} --forward --impersonate=account-expired@${R} ${ps} && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test impersonate pw-expired client"; > messages.log
+${kgetcred_imp} --forward --impersonate=pw-expired@${R} ${ps} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test delegate sensitive client"; > messages.log
+${kgetcred_imp} --forward --impersonate=sensitive@${R} ${ps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} \
+ --out-cache=${o2cache} \
+ --delegation-credential-cache=${ocache} \
+ ${server}@${R} && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test constrained delegation (evidence from impersonation)"; > messages.log
+${kgetcred_imp} --forward --impersonate=bar@${R} ${ps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} \
+ --out-cache=${o2cache} \
+ --delegation-credential-cache=${ocache} \
+ ${server}@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo " try using the credential"
+${test_ap_req} ${server}@${R} ${keytab} ${o2cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo " negative check"
+${kgetcred} \
+ --out-cache=${o2cache} \
+ --delegation-credential-cache=${ocache} \
+ bar@${R} 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test constrained delegation evidence (evidence from TGS)"; > messages.log
+echo bar > ${objdir}/barpassword
+${kinit} --cache=${icache} --forwardable --password-file=${objdir}/barpassword bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} --cache=${icache} --out-cache=${ocache} ${ps} || \
+ { ec=1 ; eval "${testfailed}"; }
+# Bug #816 have a regular ticket in ${cache} for ${server} see that it isn't used
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} \
+ --out-cache=${o2cache} \
+ --delegation-credential-cache=${ocache} \
+ ${server}@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${klist2} | grep "Principal: bar@${R}" || { ec=1 ; eval "${testfailed}"; }
+echo " try using the credential"
+${test_ap_req} ${server}@${R} ${keytab} ${o2cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo " negative check"
+${kgetcred} \
+ --out-cache=${o2cache} \
+ --delegation-credential-cache=${ocache} \
+ bar@${R} 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test constrained delegation with foreign client (evidence from TGS)"; > messages.log
+# We can't test foreign client with evidence from S4U2Self, since Heimdal doesn't support it yet
+rm -f ocache.krb5
+${kinit} --cache=${icache} --forwardable --password-file=${objdir}/foopassword foo@${R2} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} --cache=${icache} --out-cache=${ocache} ${ps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} \
+ --out-cache=${o2cache} \
+ --delegation-credential-cache=${ocache} \
+ ${server}@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${klist2} | grep "Principal: foo@${R2}" || { ec=1 ; eval "${testfailed}"; }
+echo " try using the credential"
+${test_ap_req} ${server}@${R} ${keytab} ${o2cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test constrained delegation impersonation (non forward)"; > messages.log
+rm -f ocache.krb5
+${kimpersonate} -s ${ps} -c bar@${R} -t ${aesenctype} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} --out-cache=${o2cache} --delegation-credential-cache=${ocache} ${server}@${R} > /dev/null 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test constrained delegation evidence (evidence from AS)"; > messages.log
+# This fails because we don't add PAC ticket-signature in AS-REP (as Windows).
+${kinit} --cache=${ocache} --password-file=${objdir}/barpassword \
+ --forwardable --server=${ps} bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} --delegation-credential-cache=${ocache} ${server}@${R} && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test constrained delegation impersonation (missing PAC)"; > messages.log
+rm -f ocache.krb5
+${kimpersonate} -s ${ps} -c bar@${R} -t ${aesenctype} -f forwardable || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} --out-cache=${o2cache} --delegation-credential-cache=${ocache} ${server}@${R} > /dev/null 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+${kdestroy}
+
+echo "test constrained delegation NOT trusted-for-delegation (evidence from TGS)"; > messages.log
+
+${kinit} --forwardable --password-file=${objdir}/foopassword ${rps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kinit} --cache=${icache} --forwardable --password-file=${objdir}/barpassword bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} --cache=${icache} --out-cache=${ocache} ${rps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} \
+ --out-cache=${o2cache} \
+ --delegation-credential-cache=${ocache} \
+ ${server}@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${klist2} | grep "Principal: bar@${R}" || { ec=1 ; eval "${testfailed}"; }
+${test_ap_req} ${server}@${R} ${keytab} ${o2cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test constrained delegation NOT trusted-for-delegation (evidence from impersonate, negative)"; > messages.log
+rm -f ocache.krb5
+${kgetcred_imp} --impersonate=bar@${R} ${rps} || \
+ { ec=1 ; eval "${testfailed}"; }
+${test_ap_req} ${rps} ${keytab} ${ocache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} \
+ --out-cache=${o2cache} \
+ --delegation-credential-cache=${ocache} \
+ ${server}@${R} && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "test constrained delegation bronze-bit attack, aka CVE-2020-17049"; > messages.log
+
+KRB5CCNAME=${ocache} KRB5_KTNAME=${keytab} ${test_mkforwardable} ${rps} ${icache} || \
+{ ec=1 ; eval "${testfailed}"; }
+
+${kgetcred} \
+ --out-cache=${o2cache} \
+ --delegation-credential-cache=${icache} \
+ ${server}@${R} && \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "check renewing" > messages.log
+${kinit} --renewable --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "kinit -R"
+${kinit} -R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "check renewing MIT interface" > messages.log
+${kinit} --renewable --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "test_renew"
+env KRB5CCNAME=${cache} ${test_renew} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "checking server aliases"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting tickets"; > messages.log
+${kgetcred} ${alias1}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${alias2}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo " verify entry in keytab"
+${test_ap_req} ${alias1}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo " verify entry in keytab with any"
+${test_ap_req} --server-any ${alias1}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo " verify failure with alias entry"
+${test_ap_req} ${alias2}@${R} ${keytab} ${cache} 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+echo " verify alias entry in keytab with any"
+${test_ap_req} --server-any ${alias2}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "testing removal of keytab"
+${ktutil} -k ${keytab} destroy || { ec=1 ; eval "${testfailed}"; }
+test -f ${keytabfile} && { ec=1 ; eval "${testfailed}"; }
+
+echo "Checking client pw expire"; > messages.log
+${kinit} --password-file=${objdir}/foopassword \
+ pw-expire@${R} 2>kinit-log.tmp|| \
+ { ec=1 ; eval "${testfailed}"; }
+grep 'Your password will expire' kinit-log.tmp > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+echo " kinit passes"
+${test_gic} --client=pw-expire@${R} --password=foo > kinit-log.tmp 2>/dev/null
+${EGREP} "^e type: 6" kinit-log.tmp > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+echo " test_gic passes"
+${kdestroy}
+
+echo "Checking password expiration" ; > messages.log
+
+kinitpty=${objdir}/foopassword.rkpty
+cat > ${kinitpty} <<EOF
+expect Password
+password foo\n
+expect Password has expired
+expect New password
+password Foobar11\n
+expect password
+password Foobar11\n
+expect Success: Password changed
+EOF
+
+echo "Checking client pw expire"; > messages.log
+${rkpty} ${kinitpty} ${kinit} pw-expired@${R}|| \
+ { ec=1 ; eval "${testfailed}"; }
+
+${kdestroy}
+
+
+echo "killing kdc (${kdcpid}) kpasswdd (${kpasswddpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+sh ${leaks_kill} kpasswdd $kpasswddpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-keys.in b/third_party/heimdal/tests/kdc/check-keys.in
new file mode 100644
index 0000000..6784bb5
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-keys.in
@@ -0,0 +1,104 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="."
+
+. ${env_setup}
+
+srcdir="${top_srcdir}/tests/kdc"
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+principal=host/datan.test.h5l.se@${R}
+
+kadmin="${kadmin} -l -r $R"
+
+CIN=${srcdir}/krb5.conf.keys.in
+COUT=${objdir}/krb5.conf.keys
+
+sedvars="-e s,[@]srcdir[@],${srcdir},g -e s,[@]objdir[@],${objdir},g"
+
+KRB5_CONFIG="${COUT}"
+export KRB5_CONFIG
+
+rm -f ${COUT}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+rm -f messages.log
+
+sed -e 's/@keys@/v5/' \
+ ${sedvars} < ${CIN} > ${COUT}
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p foo --use-defaults ${principal} || exit 1
+
+${kadmin} cpw -p foo ${principal} || exit 1
+
+sed -e 's/@keys@/v4/' \
+ ${sedvars} < ${CIN} > ${COUT}
+${kadmin} cpw -p foo ${principal} || exit 1
+
+sed -e 's/@keys@/v4 v5/' \
+ ${sedvars} < ${CIN} > ${COUT}
+${kadmin} cpw -p foo ${principal} || exit 1
+
+sed -e 's/@keys@/v5 v4/' \
+ ${sedvars} < ${CIN} > ${COUT}
+${kadmin} cpw -p foo ${principal} || exit 1
+
+sed -e 's/@keys@/des:pw-salt:/' \
+ ${sedvars} < ${CIN} > ${COUT}
+${kadmin} cpw -p foo ${principal} || exit 1
+
+if [ 'X@ENABLE_AFS_STRING_TO_KEY@' = "X1" ]; then
+ sed -e 's/@keys@/des-cbc-crc:afs3-salt:test.h5l.se/' \
+ ${sedvars} < ${CIN} > ${COUT}
+ ${kadmin} cpw -p foo ${principal} || exit 1
+
+ sed -e 's/@keys@/des:afs3-salt:test.h5l.se/' \
+ ${sedvars} < ${CIN} > ${COUT}
+ ${kadmin} cpw -p foo ${principal} || exit 1
+fi
+
+exit 0
diff --git a/third_party/heimdal/tests/kdc/check-kinit.in b/third_party/heimdal/tests/kdc/check-kinit.in
new file mode 100644
index 0000000..c6cb23f
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-kinit.in
@@ -0,0 +1,149 @@
+#!/bin/bash
+#
+# Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+KRB5_CONFIG="${objdir}/krb5-kinit.conf"
+export KRB5_CONFIG
+KRB5CCNAME="${objdir}/foocc"
+export KRB5CCNAME
+
+testfailed="echo test failed; exit 1"
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+pwport=@pwport@
+
+kinit="${kinit} --password-file=${objdir}/foopassword ${afs_no_afslog} -c ${objdir}/foocc"
+klist="${klist} -c ${objdir}/foocc"
+kgetcred="${kgetcred} -c ${objdir}/foocc"
+kdestroy="${kdestroy} ${afs_no_unlog}"
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+
+
+cache="FILE:${objdir}/cache.krb5"
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+
+> messages.log
+
+num_concurrent=50
+num_princs=20
+torture_time=200
+cred_life=$((torture_time / 10))
+cred_renew_life=$((torture_time / 2))
+out=${objdir}/out-kinit-torture-kgetcred
+kinit_out=${objdir}/out-kinit-torture-kinit
+
+parent_shell_proc=$$
+
+if (($# == 0)); then
+
+ echo "This is a MANUAL test."
+
+ rm -f ${keytabfile}
+ rm -f current-db*
+ rm -f out-*
+ rm -f mkey.file*
+
+ cp "${objdir}/krb5.conf" "${objdir}/krb5-kinit.conf"
+
+ echo "Creating database"
+ ${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+ echo "Adding foo"
+ ${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+
+ echo "Creating torture principals"
+ for i in $(seq 0 $((num_princs - 1)) ); do
+ ${kadmin} add -r --use-defaults svc${i}@${R} || exit 1
+ done
+
+ echo "Doing database check"
+ ${kadmin} check ${R} || exit 1
+
+ echo foo > ${objdir}/foopassword
+
+ echo Starting kdc ; > messages.log
+ ${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+ kdcpid=`getpid kdc`
+
+ trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+ ec=0
+else
+ echo "begin torture (output in $out)"
+ secs=$(date +%s)
+ cat /dev/null > "$out"
+ while (($(date +%s) < (secs + torture_time) )); do
+ echo .
+ for i in $(seq 0 1000); do
+ printf '%d\n' $((i % num_princs))
+ done | xargs -P $num_concurrent -I '{}' ${kgetcred} "svc{}@${R}"
+ ${klist} -v || exit 1
+ if ! kill -0 $parent_shell_proc; then
+ printf 'Parent shell script exited; exiting'
+ exit 1
+ grep 'Matching credential .* not found' messages.log > /dev/null &&
+ echo "THAT DID NOT WORK RIGHT"
+ fi
+ sleep 5
+ done
+ ${klist} -v
+ exit 0
+fi
+
+echo "checking that we have tickets"
+${kinit} -l $cred_life -r $cred_renew_life foo@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist} -v || { ec=1 ; eval "${testfailed}"; }
+echo "torturing"
+${kinit} -l $cred_life -r $cred_renew_life foo@${R} "$0" torture-me || { ec=1 ; eval "${testfailed}"; }
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-kpasswdd.in b/third_party/heimdal/tests/kdc/check-kpasswdd.in
new file mode 100644
index 0000000..39f12e1
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-kpasswdd.in
@@ -0,0 +1,194 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+testfailed="echo test failed; cat messages.log; exit \$ec"
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+R2=TEST2.H5L.SE
+
+port=@port@
+pwport=@pwport@
+
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+kpasswdd="${kpasswdd} --addresses=localhost -p $pwport"
+
+server=host/datan.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist="${klist} -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo "Creating database for $R"
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} add -p kaka --use-defaults ${server}@${R} || exit 1
+${kadmin} ext -k ${keytab} ${server}@${R} || exit 1
+
+echo "Creating database for ${R2}"
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R2} || exit 1
+
+${kadmin} add -p foo --use-defaults bar@${R2} || exit 1
+
+echo "Doing database check for ${R} ${R2}"
+${kadmin} check ${R} || exit 1
+${kadmin} check ${R2} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo Starting kdc ; > messages.log
+env ${HEIM_MALLOC_DEBUG} ${kdc} --detach --testing ||
+ { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+echo Starting kpasswdd
+env ${HEIM_MALLOC_DEBUG} ${kpasswdd} --detach ||
+ { echo "kpasswdd failed to start"; exit 1; }
+kpasswddpid=`getpid kpasswdd`
+
+trap "kill -9 ${kdcpid} ${kpasswddpid}; echo signal killing kdc; exit \$ec;" EXIT
+
+ec=0
+
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting tickets"; > messages.log
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Listing tickets"; > messages.log
+${klist} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${test_ap_req} ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "checking ${R}"
+
+pw=ak4unandsop39NuJ
+
+echo "Changing password"
+cat > cpw.tmp <<EOF
+expect Password
+password foo\n
+expect New password
+send ${pw}\n
+expect New password
+send ${pw}\n
+expect Success
+EOF
+
+${rkpty} cpw.tmp env ${kpasswd} foo@${R} || \
+ { ec=$? ; eval "${testfailed}"; }
+
+rm cpw.tmp
+
+echo ${pw} > ${objdir}/barpassword
+
+
+echo "Getting client initial tickets for ${R}"; > messages.log
+${kinit} --password-file=${objdir}/barpassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting tickets"; > messages.log
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Listing tickets"; > messages.log
+${klist} > /dev/null || { ec=1 ; eval "${testfailed}"; }
+${test_ap_req} ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+
+echo "checking ${R2}"
+
+cat > cpw.tmp <<EOF
+expect Password
+password foo\n
+expect New password
+send ${pw}\n
+expect New password
+send ${pw}\n
+expect Success
+EOF
+
+${rkpty} cpw.tmp ../../kpasswd/kpasswd bar@${R2} || \
+ { ec=$? ; eval "${testfailed}"; }
+
+rm cpw.tmp
+
+
+echo "Getting client initial tickets for ${R2}"; > messages.log
+${kinit} --password-file=${objdir}/barpassword bar@${R2} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+
+echo "killing kdc (${kdcpid} ${kpasswddpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+sh ${leaks_kill} kpasswdd $kpasswddpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-pkinit.in b/third_party/heimdal/tests/kdc/check-pkinit.in
new file mode 100644
index 0000000..571a64e
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-pkinit.in
@@ -0,0 +1,393 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+
+port=@port@
+
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+
+server=host/datan.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+keyfile="${hx509_data}/key.der"
+keyfile2="${hx509_data}/key2.der"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klistjson="${klist} --json -c $cache"
+klistplain="${klist} -c $cache"
+klist="${klist} --hidden -v -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+kx509="${kx509} -c $cache"
+
+KRB5_CONFIG="${objdir}/krb5-pkinit.conf"
+export KRB5_CONFIG
+HEIM_PIDFILE_DIR=$objdir
+export HEIM_PIDFILE_DIR
+HEIM_IPC_DIR=$objdir
+export HEIM_IPC_DIR
+
+
+rsa=yes
+pkinit=no
+if ${hxtool} info | grep 'rsa: hx509 null RSA' > /dev/null ; then
+ rsa=no
+fi
+if ${hxtool} info | grep 'rand: not available' > /dev/null ; then
+ rsa=no
+fi
+
+if ${kinit} --help 2>&1 | grep "CA certificates" > /dev/null; then
+ pkinit=yes
+fi
+
+# If we doesn't support pkinit and have RSA, give up
+if test "$pkinit" != yes -o "$rsa" != yes ; then
+ exit 77
+fi
+
+
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} modify --max-ticket-life=5d krbtgt/${R}@${R} || exit 1
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} add -p bar --use-defaults bar@${R} || exit 1
+${kadmin} add -p baz --use-defaults baz@${R} || exit 1
+${kadmin} add -p foo --use-defaults host/server.test.h5l.se@${R} || exit 1
+${kadmin} modify --alias=baz2\\@test.h5l.se@${R} baz@${R} || exit 1
+${kadmin} modify --pkinit-acl="CN=baz,DC=test,DC=h5l,DC=se" baz@${R} || exit 1
+
+${kadmin} add -p kaka --use-defaults ${server}@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+# XXX Do not use committed, in-tree private keys or certificates!
+# XXX Add hxtool command to generate a private key w/o generating a CSR
+# XXX Use hxtool to generate a fresh private key
+# XXX Use hxtool to generate self-signed CA certs
+# XXX Use PEM-FILE and store private key and certificate in same file
+# XXX Update krb5.conf.in to use ${objdir}-relative keys and certificates
+
+echo "Setting up certificates"
+${hxtool} request-create \
+ --subject="CN=kdc,DC=test,DC=h5l,DC=se" \
+ --key=FILE:${keyfile2} \
+ req-kdc.der || exit 1
+${hxtool} request-create \
+ --subject="CN=bar,DC=test,DC=h5l,DC=se" \
+ --key=FILE:${keyfile2} \
+ req-pkinit.der || exit 1
+${hxtool} request-create \
+ --subject="CN=baz,DC=test,DC=h5l,DC=se" \
+ --key=FILE:${keyfile2} \
+ req-pkinit2.der || exit 1
+
+echo "issue self-signed ca cert"
+${hxtool} issue-certificate \
+ --self-signed \
+ --issue-ca \
+ --ca-private-key=FILE:${keyfile} \
+ --subject="CN=CA,DC=test,DC=h5l,DC=se" \
+ --certificate="FILE:ca.crt" || exit 1
+
+echo "issue kdc certificate"
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-kdc" \
+ --pk-init-principal="krbtgt/TEST.H5L.SE@TEST.H5L.SE" \
+ --req="PKCS10:req-kdc.der" \
+ --certificate="FILE:kdc.crt" || exit 1
+
+echo "issue user certificate (pkinit san)"
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --pk-init-principal="bar@TEST.H5L.SE" \
+ --req="PKCS10:req-pkinit.der" \
+ --lifetime=7d \
+ --certificate="FILE:pkinit.crt" || exit 1
+
+echo "issue user certificate (pkinit san; synthetic principal)"
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --pk-init-principal="synthetized@TEST.H5L.SE" \
+ --req="PKCS10:req-pkinit.der" \
+ --lifetime=7d \
+ --certificate="FILE:pkinit-synthetic.crt" || exit 1
+
+echo "issue user 2 certificate (no san)"
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --req="PKCS10:req-pkinit2.der" \
+ --certificate="FILE:pkinit2.crt" || exit 1
+
+echo "issue user 3 certificate (ms san)"
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --ms-upn="bar@test.h5l.se" \
+ --req="PKCS10:req-pkinit2.der" \
+ --certificate="FILE:pkinit3.crt" || exit 1
+
+echo "issue user 3 certificate (ms san, baz2)"
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --ms-upn="baz2\\@test.h5l.se@${R}" \
+ --req="PKCS10:req-pkinit2.der" \
+ --certificate="FILE:pkinit4.crt" || exit 1
+
+echo "issue self-signed kx509 template cert"
+${hxtool} issue-certificate \
+ --self-signed \
+ --ca-private-key=FILE:${keyfile} \
+ --subject='CN=${principal-component0},DC=test,DC=h5l,DC=se' \
+ --certificate="FILE:kx509-template.crt" || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo Starting kdc ; > messages.log
+KRB5_CONFIG="${objdir}/krb5-pkinit2.conf"
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap 'kill -9 ${kdcpid}; echo signal killing kdc; cat ca.crt kdc.crt pkinit.crt pkinit-synthetic.crt; exit 1;' EXIT
+
+ec=0
+
+echo "Trying pk-init (principal in cert; longer max_life)"; > messages.log
+base="${objdir}"
+${kinit} --lifetime=5d -C FILE:${base}/pkinit.crt,${keyfile2} bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist}
+if jq --version >/dev/null 2>&1 && jq -ne true >/dev/null 2>&1; then
+ ${klistjson} |
+ jq -e '(((.tickets[0].Expires|
+ strptime("%b %d %H:%M:%S %Y")|mktime) - now) / 86400) |
+ (floor < 4)' >/dev/null &&
+ { ec=1 ; eval "${testfailed}"; }
+fi
+${kdestroy}
+
+echo "Trying pk-init (principal in cert; synthetic)"; > messages.log
+base="${objdir}"
+${kinit} --lifetime=5d -C FILE:${base}/pkinit-synthetic.crt,${keyfile2} synthetized@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist}
+${kdestroy}
+
+echo "Restarting kdc ($kdcpid)"
+sh ${leaks_kill} kdc $kdcpid || ec=1
+KRB5_CONFIG="${objdir}/krb5-pkinit.conf"
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+echo "Trying pk-init (principal in cert)"; > messages.log
+base="${objdir}"
+${kinit} -C FILE:${base}/pkinit.crt,${keyfile2} bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist}
+if jq --version >/dev/null 2>&1 && jq -ne true >/dev/null 2>&1; then
+ ${klistjson} |
+ jq -e '(((.tickets[0].Expires|
+ strptime("%b %d %H:%M:%S %Y")|mktime) - now) / 86400) |
+ (floor > 1)' >/dev/null &&
+ { ec=1 ; eval "${testfailed}"; }
+fi
+${kdestroy}
+
+echo "Trying pk-init (principal in cert; longer max_life from cert ext)"; > messages.log
+# Re-issue cert with --pkinit-max-life=7d
+${hxtool} issue-certificate \
+ --ca-certificate=FILE:$objdir/ca.crt,${keyfile} \
+ --type="pkinit-client" \
+ --pk-init-principal="bar@TEST.H5L.SE" \
+ --req="PKCS10:req-pkinit.der" \
+ --lifetime=7d \
+ --pkinit-max-life=7d \
+ --certificate="FILE:pkinit.crt" || exit 1
+base="${objdir}"
+${kinit} --lifetime=5d -C FILE:${base}/pkinit.crt,${keyfile2} bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${klist}
+if jq --version >/dev/null 2>&1 && jq -ne true >/dev/null 2>&1; then
+ ${klistjson} |
+ jq -e '(((.tickets[0].Expires|
+ strptime("%b %d %H:%M:%S %Y")|mktime) - now) / 86400) |
+ (floor < 4)' >/dev/null &&
+ { ec=1 ; eval "${testfailed}"; }
+fi
+
+echo "Check kx509 certificate acquisition"
+${kx509} -s || { ec=1 ; eval "${testfailed}"; }
+${kx509} -o PEM-FILE:${objdir}/kx509.pem || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Check PKINIT w/ kx509 certificate"
+${kinit} -C PEM-FILE:${objdir}/kx509.pem bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Trying pk-init (principal in pki-mapping file) "; > messages.log
+${kinit} -C FILE:${base}/pkinit.crt,${keyfile2} foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying pk-init (principal subject in DB)"; > messages.log
+${kinit} -C FILE:${base}/pkinit2.crt,${keyfile2} baz@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying pk-init (ms upn)"; > messages.log
+${kinit} -C FILE:${base}/pkinit3.crt,${keyfile2} bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying pk-init (ms upn, enterprise)"; > messages.log
+${kinit} --canonicalize --enterprise \
+ -C FILE:${base}/pkinit4.crt,${keyfile2} baz2@test.h5l.se || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying pk-init (ms upn, enterprise, pk-enterprise)"; > messages.log
+${kinit} --canonicalize \
+ --pk-enterprise \
+ -C FILE:${base}/pkinit4.crt,${keyfile2} ${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+KRB5_CONFIG="${objdir}/krb5-pkinit-win.conf"
+export KRB5_CONFIG
+
+echo "Duplicated tests, now in windows 2000 mode"
+
+echo "Trying pk-init (principal in cert)"; > messages.log
+base="${objdir}"
+${kinit} -C FILE:${base}/pkinit.crt,${keyfile2} bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying pk-init (principal in pki-mapping file) "; > messages.log
+${kinit} -C FILE:${base}/pkinit.crt,${keyfile2} foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying pk-init (principal subject in DB)"; > messages.log
+${kinit} -C FILE:${base}/pkinit2.crt,${keyfile2} baz@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Trying pk-init (ms upn)"; > messages.log
+${kinit} -C FILE:${base}/pkinit3.crt,${keyfile2} bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+
+KRB5_CONFIG="${objdir}/krb5-pkinit.conf"
+export KRB5_CONFIG
+
+echo "Trying PKCS11 support"
+
+cat > test-rc-file.rc <<EOF
+certificate cert User certificate FILE:${base}/pkinit.crt,${keyfile2}
+app-fatal true
+EOF
+
+SOFTPKCS11RC="test-rc-file.rc"
+export SOFTPKCS11RC
+
+dir=${base}/../../lib/hx509
+file=
+
+for a in libhx509.so .libs/libhx509.so libhx509.dylib .libs/libhx509.dylib ; do
+ if [ -f $dir/$a ] ; then
+ file=$dir/$a
+ break
+ fi
+done
+
+if [ X"$file" != X -a @DLOPEN@ ] ; then
+
+ echo "Trying pk-init (principal in pki-mapping file) "; > messages.log
+ ${kinit} -C PKCS11:${file} foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+ ${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+ ${kdestroy}
+
+fi
+
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || ec=1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-referral.in b/third_party/heimdal/tests/kdc/check-referral.in
new file mode 100644
index 0000000..49f6a52
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-referral.in
@@ -0,0 +1,301 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+d=test.h5l.se
+d2=xtst.heim.example
+R=TEST.H5L.SE
+R2=XTST.HEIM.EXAMPLE
+
+# $service1 will be a hard alias of $service2
+service1=ldap/host.${d}:389
+service2=ldap/host.${d2}:389
+# $service3 and $service4 will have soft aliases referrals from each
+# other's realms
+service3=host/foohost.${d}
+service4=host/barhost.${d2}
+# $service5 and $service6 will be hardaliases
+service5=host/thing1.${d}
+service6=host/thing1.${d2}
+# $service7 and $service8 will be hardaliases in the opposite direction
+service7=host/thing2.${d}
+service8=host/thing2.${d2}
+
+port=@port@
+
+kadmin="${kadmin} -l -r $R"
+kdc="${kdc} --addresses=localhost -P $port"
+
+cache="FILE:${objdir}/cache.krb5"
+
+kinit="${kinit} -c $cache ${afs_no_afslog}"
+klist="${klist} -c $cache"
+kgetcred="${kgetcred} -c $cache"
+kdestroy="${kdestroy} -c $cache ${afs_no_unlog}"
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+KRB5CCNAME=$cache
+export KRB5CCNAME
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R2} || exit 1
+
+${kadmin} add -r --use-defaults WELLKNOWN/REFERRALS/TARGET@${R} || exit 1
+${kadmin} add -r --use-defaults WELLKNOWN/REFERRALS/TARGET@${R2} || exit 1
+
+# User 'foo' gets two aliases in the same realm, and one in the other
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} add_alias foo@${R} foo@${R2} alias1 alias2 || exit 1
+${kadmin} get foo@${R} | grep alias1@${R} >/dev/null || exit 1
+${kadmin} get foo@${R} | grep alias2@${R} >/dev/null || exit 1
+${kadmin} get foo@${R} | grep foo@${R2} >/dev/null || exit 1
+
+# service1 is an alias of service2, in different realms
+${kadmin} add -p foo --use-defaults ${service2}@${R2} || exit 1
+${kadmin} add_alias ${service2}@${R2} ${service1}@${R} || exit 1
+${kadmin} get ${service2}@${R2} | grep ${service1}@${R} >/dev/null || exit 1
+
+# service3 and service4 get soft aliases in each other's realms
+${kadmin} add -p foo --use-defaults ${service3}@${R} || exit 1
+${kadmin} add -p foo --use-defaults ${service4}@${R2} || exit 1
+${kadmin} add_alias WELLKNOWN/REFERRALS/TARGET@${R2} ${service4}@${R} || exit 1
+${kadmin} add_alias WELLKNOWN/REFERRALS/TARGET@${R} ${service3}@${R2} || exit 1
+
+# service6 is a hard alias of service5
+${kadmin} add -p foo --use-defaults ${service5}@${R} || exit 1
+${kadmin} add_alias ${service5}@${R} ${service6}@${R2} || exit 1
+
+# service8 is a hard alias of service7, but in the opposite direction
+${kadmin} add -p foo --use-defaults ${service7}@${R2} || exit 1
+${kadmin} add_alias ${service5}@${R} ${service8}@${R} || exit 1
+
+${kadmin} add -p foo --use-defaults bar@${R} || exit 1
+${kadmin} add -p foo --use-defaults 'baz\@realm.foo@'${R} || exit 1
+
+${kadmin} add -p cross1 --use-defaults krbtgt/${R2}@${R} || exit 1
+${kadmin} add -p cross2 --use-defaults krbtgt/${R}@${R2} || exit 1
+
+${kadmin} ext -k ${keytab} krbtgt/${R}@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+${kadmin} check ${R2} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo Starting kdc ; > messages.log
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+ec=0
+
+
+echo "Getting client bar"; > messages.log
+${kinit} --password-file=${objdir}/foopassword bar@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep "Principal: bar@${R}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client baz"; > messages.log
+${kinit} --password-file=${objdir}/foopassword 'baz\@realm.foo@'${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep 'Principal: baz' > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+
+
+echo "Test AS-REQ"
+
+echo "Getting client (no canon)"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep "Principal: foo@${R}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client client tickets (default realm, enterprisename)"; > messages.log
+${kinit} --canonicalize --enterprise \
+ --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep "Principal: foo@${R}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal inside the PAC"
+${test_ap_req} krbtgt/${R}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client alias1 tickets"; > messages.log
+${kinit} --canonicalize --enterprise \
+ --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep "Principal: foo@${R}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal inside the PAC"
+${test_ap_req} krbtgt/${R}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+
+echo "Getting client alias2 tickets"; > messages.log
+${kinit} --canonicalize --enterprise \
+ --password-file=${objdir}/foopassword alias2@${R}@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep "Principal: foo@${R}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal inside the PAC"
+${test_ap_req} krbtgt/${R}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client alias1 tickets (non canon case)"; > messages.log
+${kinit} --password-file=${objdir}/foopassword alias1@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep "Principal: alias1@${R}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal inside the PAC"
+${test_ap_req} krbtgt/${R}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service2}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service1}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client foo@${R2} tickets (non canon case)"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@${R2} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep "Principal: foo@${R2}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal inside the PAC"
+${test_ap_req} krbtgt/${R}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting various service tickets using foo@${R2} client"
+${kgetcred} ${service2}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service1}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service1}@${R2} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service2}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service3}@ || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service4}@ || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service5}@ || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service6}@ || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service7}@ || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service8}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client alias2 tickets (removed)"; > messages.log
+${kadmin} modify --alias=alias1 foo@${R} || { ec=1 ; eval "${testfailed}"; }
+${kinit} --canonicalize --enterprise \
+ --password-file=${objdir}/foopassword \
+ alias2@${R}@${R} > /dev/null 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Remove alias"
+${kadmin} modify --alias= foo@${R} || { ec=1 ; eval "${testfailed}"; }
+
+echo "Test server referrals"
+
+echo "Getting client for ${service2}@${R} (tgs kdc referral)"
+> messages.log
+${kinit} --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} --canonicalize ${service2}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service3}@${R} || { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service4}@ || { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep "${service2}@${R2}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${klist} | grep "${service4}@${R}" > /dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+${klist} | grep "${service4}@${R2}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client for ${service2}@${R2} (tgs client side guessing)"
+> messages.log
+${kinit} --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kgetcred} ${service2}@${R2} ||
+ { ec=1 ; eval "${testfailed}"; }
+echo "checking that we got back right principal"
+${klist} | grep "${service2}@${R2}" > /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+
+echo "killing kdc (${kdcpid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-tester.in b/third_party/heimdal/tests/kdc/check-tester.in
new file mode 100644
index 0000000..83b48ba
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-tester.in
@@ -0,0 +1,121 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+top_builddir="@top_builddir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+srcdir="@srcdir@"
+
+. ${env_setup}
+
+KRB5_CONFIG="${1-${objdir}/krb5.conf}"
+export KRB5_CONFIG
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+# Do not run in GutHub valgrind builds -- too slow / not necessary
+[ -n "$CHECK_TESTER_NO_VALGRIND" ] && exit 77
+
+R=TEST.H5L.SE
+
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+keyfile="${hx509_data}/key.der"
+keyfile2="${hx509_data}/key2.der"
+
+kadmin="${kadmin} -l -r $R"
+
+server=host/datan.test.h5l.se
+
+rsa=yes
+pkinit=no
+if ${hxtool} info | grep 'rsa: hx509 null RSA' > /dev/null ; then
+ rsa=no
+fi
+if ${hxtool} info | grep 'rand: not available' > /dev/null ; then
+ rsa=no
+fi
+
+if ${kinit} --help 2>&1 | grep "CA certificates" > /dev/null; then
+ pkinit=yes
+fi
+
+# If we doesn't support pkinit and have RSA, give up
+if test "$rsa" != yes ; then
+ pkinit=no
+fi
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p foo --use-defaults ${server}@${R} || exit 1
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} ext -k ${keytab} foo@${R} || exit 1
+${kadmin} ext -k ${keytab} ${server}@${R} || exit 1
+
+echo "password"
+${kdc_tester} ${srcdir}/kdc-tester1.json > out-log 2>&1 || exit 1
+sed 's/^/ /' out-log
+
+echo "keytab"
+${kdc_tester} ${srcdir}/kdc-tester2.json > out-log 2>&1 || exit 1
+sed 's/^/ /' out-log
+
+echo "FAST + keytab"
+${kdc_tester} ${srcdir}/kdc-tester3.json > out-log 2>&1 || exit 1
+sed 's/^/ /' out-log
+
+
+if test "$pkinit" = yes ; then
+
+ echo "pkinit"
+ ${kdc_tester} ${objdir}/kdc-tester4.json > out-log 2>&1 || exit 1
+ sed 's/^/ /' out-log
+
+fi
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/check-uu.in b/third_party/heimdal/tests/kdc/check-uu.in
new file mode 100644
index 0000000..ef831ca
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/check-uu.in
@@ -0,0 +1,131 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+env_setup="@env_setup@"
+objdir="@objdir@"
+srcdir="@srcdir@"
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+. ${env_setup}
+
+# If there is no useful db support compiled in, disable test
+${have_db} || exit 77
+
+R=TEST.H5L.SE
+
+uuspid=
+
+port=@port@
+
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r $R"
+kdc="${TESTS_ENVIRONMENT} ../../kdc/kdc --addresses=localhost -P $port"
+
+cache1="FILE:${objdir}/cache1.krb5"
+cache2="FILE:${objdir}/cache2.krb5"
+
+kinit1="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cache1 ${afs_no_afslog}"
+kinit2="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cache2 ${afs_no_afslog}"
+kdestroy1="${TESTS_ENVIRONMENT} ../../kuser/kdestroy -c $cache1 ${afs_no_unlog}"
+kdestroy2="${TESTS_ENVIRONMENT} ../../kuser/kdestroy -c $cache2 ${afs_no_unlog}"
+uu_server="${TESTS_ENVIRONMENT} ../../appl/test/uu_server"
+uu_client="${TESTS_ENVIRONMENT} ../../appl/test/uu_client"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p foo --use-defaults user1@${R} || exit 1
+${kadmin} add -p foo --use-defaults user2@${R} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo Starting kdc ; > messages.log
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill -9 ${kdcpid} ${uuspid}; echo signal killing kdc; exit 1;" EXIT
+
+ec=0
+
+echo "Getting client initial tickets user1"; > messages.log
+${kinit1} --password-file=${objdir}/foopassword user1@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting client initial tickets user2"; > messages.log
+${kinit2} --password-file=${objdir}/foopassword user2@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+
+
+echo "starting uu server (using user1)"
+KRB5CCNAME=$cache1 ${uu_server} > uuserver.log &
+uuspid=$!
+sleep 5
+
+echo "trying to contact server with client (using user2)"
+KRB5CCNAME=$cache2 ${uu_client} localhost > messages.log 2>&1 || \
+ { ec=1; eval "${testfailed}"; }
+
+sleep 5
+
+echo "checking if server got the right message"
+cmp uuserver.log ${srcdir}/uuserver.txt || \
+ { ec=1; eval "${testfailed}"; }
+
+uuspid=""
+
+${kdestroy1}
+${kdestroy2}
+
+echo "killing kdc uu_server (${kdcpid} ${uuspid})"
+sh ${leaks_kill} kdc $kdcpid || exit 1
+
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/kdc/donotexists.txt b/third_party/heimdal/tests/kdc/donotexists.txt
new file mode 100644
index 0000000..5294397
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/donotexists.txt
@@ -0,0 +1 @@
+kadmin: get doesnotexists@TEST.H5L.SE: Principal does not exist
diff --git a/third_party/heimdal/tests/kdc/hdb-mitdb b/third_party/heimdal/tests/kdc/hdb-mitdb
new file mode 100644
index 0000000..00fefb9
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/hdb-mitdb
Binary files differ
diff --git a/third_party/heimdal/tests/kdc/hdb-mitdb.kadm5 b/third_party/heimdal/tests/kdc/hdb-mitdb.kadm5
new file mode 100644
index 0000000..41663b9
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/hdb-mitdb.kadm5
Binary files differ
diff --git a/third_party/heimdal/tests/kdc/hdb-mitdb.mkey b/third_party/heimdal/tests/kdc/hdb-mitdb.mkey
new file mode 100644
index 0000000..627c0fa
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/hdb-mitdb.mkey
Binary files differ
diff --git a/third_party/heimdal/tests/kdc/heimdal.acl b/third_party/heimdal/tests/kdc/heimdal.acl
new file mode 100644
index 0000000..2888a25
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/heimdal.acl
@@ -0,0 +1,10 @@
+foo/admin@TEST.H5L.SE all
+httpkadmind/admin@TEST.H5L.SE all,get-keys
+bar@TEST.H5L.SE all
+baz@TEST.H5L.SE get,add *
+bez@TEST.H5L.SE get,add *@TEST.H5L.SE
+fez@TEST.H5L.SE get,add
+hasalias@TEST.H5L.SE get,mod hasalias@TEST.H5L.SE
+hasalias@TEST.H5L.SE get,add goodalias1@TEST.H5L.SE
+hasalias@TEST.H5L.SE get,add goodalias2@TEST.H5L.SE
+hasalias@TEST.H5L.SE get,add goodalias3@TEST.H5L.SE
diff --git a/third_party/heimdal/tests/kdc/iprop-acl b/third_party/heimdal/tests/kdc/iprop-acl
new file mode 100644
index 0000000..334a407
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/iprop-acl
@@ -0,0 +1 @@
+iprop/slave.test.h5l.se@TEST.H5L.SE
diff --git a/third_party/heimdal/tests/kdc/k5login/foo b/third_party/heimdal/tests/kdc/k5login/foo
new file mode 100644
index 0000000..b51a40b
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/k5login/foo
@@ -0,0 +1 @@
+random-princ@RANDOM-REALM
diff --git a/third_party/heimdal/tests/kdc/k5login/mapped_user1 b/third_party/heimdal/tests/kdc/k5login/mapped_user1
new file mode 100644
index 0000000..a7857c2
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/k5login/mapped_user1
@@ -0,0 +1 @@
+user1@TEST.H5L.SE
diff --git a/third_party/heimdal/tests/kdc/kdc-tester1.json b/third_party/heimdal/tests/kdc/kdc-tester1.json
new file mode 100644
index 0000000..08a7744
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/kdc-tester1.json
@@ -0,0 +1,31 @@
+[
+ {
+ "op" : "repeat",
+ "num" : 333,
+ "value" : {
+ "op" : "kinit",
+ "client" : "foo@TEST.H5L.SE",
+ "password" : "foo"
+ }
+ },
+ {
+ "op" : "kinit",
+ "client" : "foo@TEST.H5L.SE",
+ "password" : "foo",
+ "ccache" : "MEMORY:cache"
+ },
+ {
+ "op" : "repeat",
+ "num" : 333,
+ "value" : {
+ "op" : "kgetcred",
+ "server" : "host/datan.test.h5l.se@TEST.H5L.SE",
+ "ccache" : "MEMORY:cache"
+ }
+ },
+ {
+ "op" : "kdestroy",
+ "ccache" : "MEMORY:cache"
+ }
+]
+
diff --git a/third_party/heimdal/tests/kdc/kdc-tester2.json b/third_party/heimdal/tests/kdc/kdc-tester2.json
new file mode 100644
index 0000000..207ae37
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/kdc-tester2.json
@@ -0,0 +1,12 @@
+[
+ {
+ "op" : "repeat",
+ "num" : 333,
+ "value" : {
+ "op" : "kinit",
+ "client" : "foo@TEST.H5L.SE",
+ "keytab" : "FILE:server.keytab"
+ }
+ }
+]
+
diff --git a/third_party/heimdal/tests/kdc/kdc-tester3.json b/third_party/heimdal/tests/kdc/kdc-tester3.json
new file mode 100644
index 0000000..682e485
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/kdc-tester3.json
@@ -0,0 +1,23 @@
+[
+ {
+ "op" : "kinit",
+ "client" : "host/datan.test.h5l.se@TEST.H5L.SE",
+ "keytab" : "FILE:server.keytab",
+ "ccache" : "MEMORY:fast-cc"
+ },
+ {
+ "op" : "repeat",
+ "num" : 333,
+ "value" : {
+ "op" : "kinit",
+ "client" : "foo@TEST.H5L.SE",
+ "keytab" : "FILE:server.keytab",
+ "fast-armor-cc" : "MEMORY:fast-cc"
+ }
+ },
+ {
+ "op" : "kdestroy",
+ "ccache" : "MEMORY:fast-cc"
+ }
+]
+
diff --git a/third_party/heimdal/tests/kdc/kdc-tester4.json.in b/third_party/heimdal/tests/kdc/kdc-tester4.json.in
new file mode 100644
index 0000000..0cbc337
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/kdc-tester4.json.in
@@ -0,0 +1,22 @@
+[
+ {
+ "op" : "repeat",
+ "num" : 333,
+ "value" : {
+ "op" : "kinit",
+ "client" : "foo@TEST.H5L.SE",
+ "pkinit-user-cert-id" : "FILE:@top_srcdir@/lib/hx509/data/pkinit.crt,@top_srcdir@/lib/hx509/data/pkinit.key"
+ }
+ },
+ {
+ "op" : "repeat",
+ "num" : 333,
+ "value" : {
+ "op" : "kinit",
+ "client" : "foo@TEST.H5L.SE",
+ "pkinit-user-cert-id" : "FILE:@top_srcdir@/lib/hx509/data/pkinit.crt,@top_srcdir@/lib/hx509/data/pkinit.key",
+ "pkinit-use-rsa" : true
+ }
+ }
+]
+
diff --git a/third_party/heimdal/tests/kdc/krb5-authz.conf.in b/third_party/heimdal/tests/kdc/krb5-authz.conf.in
new file mode 100644
index 0000000..0d4f38b
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-authz.conf.in
@@ -0,0 +1,26 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE TEST2.H5L.SE TEST3.H5L.SE
+ no-addresses = TRUE
+ kuserok = SYSTEM-K5LOGIN:@srcdir@/k5login
+ kuserok = USER-K5LOGIN
+ kuserok = SIMPLE
+
+[appdefaults]
+
+[realms]
+ TEST.H5L.SE = {
+ auth_to_local_names = {
+ foo/mapped1 = foo
+ foo/mapped2 = bar
+ mapped1 = foo
+ mapped2 = bar
+ }
+ auth_to_local = DB:@srcdir@/an2ln-db.txt DEFAULT
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ default = 0-/FILE:@objdir@/messages.log
+
diff --git a/third_party/heimdal/tests/kdc/krb5-authz2.conf.in b/third_party/heimdal/tests/kdc/krb5-authz2.conf.in
new file mode 100644
index 0000000..9a8efb0
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-authz2.conf.in
@@ -0,0 +1,27 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE TEST2.H5L.SE TEST3.H5L.SE
+ no-addresses = TRUE
+ k5login_authoritative = TRUE
+ k5login_directory = @srcdir@/k5login
+ kuserok = SYSTEM-K5LOGIN
+ kuserok = SIMPLE
+
+[appdefaults]
+
+[realms]
+ TEST.H5L.SE = {
+ auth_to_local_names = {
+ foo/mapped1 = foo
+ foo/mapped2 = bar
+ mapped1 = foo
+ mapped2 = bar
+ }
+ auth_to_local = DB:@srcdir@/an2ln-db.txt DEFAULT
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ default = 0-/FILE:@objdir@/messages.log
+
diff --git a/third_party/heimdal/tests/kdc/krb5-bx509.conf.in b/third_party/heimdal/tests/kdc/krb5-bx509.conf.in
new file mode 100644
index 0000000..2cd6fef
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-bx509.conf.in
@@ -0,0 +1,182 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE
+ no-addresses = TRUE
+ allow_weak_crypto = TRUE
+ rdns = false
+ fcache_strict_checking = false
+ name_canon_rules = as-is:realm=TEST.H5L.SE
+
+[appdefaults]
+ pkinit_anchors = FILE:@objdir@/pkinit-anchor.pem
+ pkinit_pool = FILE:@objdir@/pkinit-anchor.pem
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ pkinit_win2k = @w2k@
+ }
+
+[kdc]
+ check-ticket-addresses = no
+ warn_ticket_addresses = yes
+ num-kdc-processes = 1
+ strict-nametypes = true
+ enable-pkinit = true
+ pkinit_identity = PEM-FILE:@objdir@/user-issuer.pem
+ pkinit_anchors = PEM-FILE:@objdir@/pkinit-anchor.pem
+ pkinit_mappings_file = @srcdir@/pki-mapping
+
+ # Locate kdc plugins for testing
+ plugin_dir = @objdir@/../../kdc/.libs
+
+ enable-pkinit = true
+ pkinit_identity = PEM-FILE:@objdir@/user-issuer.pem
+ pkinit_anchors = PEM-FILE:@objdir@/pkinit-anchor.pem
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_max_life_from_cert = 5d
+
+ database = {
+ dbname = @objdir@/current-db
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ log_file = @objdir@/log.current-db.log
+ }
+
+ negotiate_token_validator = {
+ keytab = FILE:@objdir@/kt
+ }
+
+ realms = {
+ TEST.H5L.SE = {
+ kx509 = {
+ user = {
+ include_pkinit_san = true
+ subject_name = CN=${principal-name-without-realm},DC=test,DC=h5l,DC=se
+ ekus = 1.3.6.1.5.5.7.3.2
+ ca = PEM-FILE:@objdir@/user-issuer.pem
+ }
+ hostbased_service = {
+ HTTP = {
+ include_dnsname_san = true
+ ekus = 1.3.6.1.5.5.7.3.1
+ ca = PEM-FILE:@objdir@/server-issuer.pem
+ }
+ }
+ client = {
+ ekus = 1.3.6.1.5.5.7.3.2
+ ca = PEM-FILE:@objdir@/user-issuer.pem
+ }
+ server = {
+ ekus = 1.3.6.1.5.5.7.3.1
+ ca = PEM-FILE:@objdir@/server-issuer.pem
+ }
+ mixed = {
+ ekus = 1.3.6.1.5.5.7.3.1
+ ekus = 1.3.6.1.5.5.7.3.2
+ ca = PEM-FILE:@objdir@/mixed-issuer.pem
+ }
+ }
+ }
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[bx509]
+ realms = {
+ TEST.H5L.SE = {
+ # Default (no cert exts requested)
+ user = {
+ # Use an issuer for user certs:
+ ca = PEM-FILE:@objdir@/user-issuer.pem
+ subject_name = CN=${principal-name-without-realm},DC=test,DC=h5l,DC=se
+ ekus = 1.3.6.1.5.5.7.3.2
+ include_pkinit_san = true
+ }
+ hostbased_service = {
+ # Only for HTTP services
+ HTTP = {
+ # Use an issuer for server certs:
+ ca = PEM-FILE:@objdir@/server-issuer.pem
+ include_dnsname_san = true
+ # Don't bother with a template
+ }
+ }
+ # Non-default certs (extensions requested)
+ #
+ # Use no templates -- get empty subject names,
+ # use SANs.
+ #
+ # Use appropriate issuers.
+ client = {
+ ca = PEM-FILE:@objdir@/user-issuer.pem
+ }
+ server = {
+ ca = PEM-FILE:@objdir@/server-issuer.pem
+ }
+ mixed = {
+ ca = PEM-FILE:@objdir@/mixed-issuer.pem
+ }
+ }
+ }
+
+[get-tgt]
+ no_addresses = true
+ allow_addresses = true
+ realms = {
+ TEST.H5L.SE = {
+ # Default (no cert exts requested)
+ client = {
+ # Use an issuer for user certs:
+ ca = PEM-FILE:@objdir@/user-issuer.pem
+ subject_name = CN=${principal-name-without-realm},DC=test,DC=h5l,DC=se
+ ekus = 1.3.6.1.5.5.7.3.2
+ include_pkinit_san = true
+ allow_extra_lifetime = true
+ max_cert_lifetime = 7d
+ force_cert_lifetime = 2d
+ }
+ user = {
+ # Use an issuer for user certs:
+ ca = PEM-FILE:@objdir@/user-issuer.pem
+ subject_name = CN=${principal-name-without-realm},DC=test,DC=h5l,DC=se
+ ekus = 1.3.6.1.5.5.7.3.2
+ include_pkinit_san = true
+ allow_extra_lifetime = true
+ max_cert_lifetime = 7d
+ force_cert_lifetime = 2d
+ }
+ hostbased_service = {
+ # Only for HTTP services
+ HTTP = {
+ # Use an issuer for server certs:
+ ca = PEM-FILE:@objdir@/server-issuer.pem
+ include_dnsname_san = true
+ # Don't bother with a template
+ }
+ }
+ # Non-default certs (extensions requested)
+ #
+ # Use no templates -- get empty subject names,
+ # use SANs.
+ #
+ # Use appropriate issuers.
+ client = {
+ ca = PEM-FILE:@objdir@/user-issuer.pem
+ }
+ server = {
+ ca = PEM-FILE:@objdir@/server-issuer.pem
+ }
+ mixed = {
+ ca = PEM-FILE:@objdir@/mixed-issuer.pem
+ }
+ }
+ }
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ bx509d = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+[domain_realm]
+ . = TEST.H5L.SE
diff --git a/third_party/heimdal/tests/kdc/krb5-canon.conf.in b/third_party/heimdal/tests/kdc/krb5-canon.conf.in
new file mode 100644
index 0000000..0ce45b5
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-canon.conf.in
@@ -0,0 +1,100 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE TEST2.H5L.SE
+ no-addresses = TRUE
+ dns_lookup_realm = no
+ name_canon_rules = as-is:realm=TEST.H5L.SE
+ name_canon_rules = as-is:realm=TEST2.H5L.SE
+ name_canon_rules = as-is:realm=TEST3.H5L.SE
+ name_canon_rules = qualify:domain=test1.h5l.se:realm=TEST.H5L.SE
+ name_canon_rules = qualify:domain=test1.h5l.se:realm=TEST2.H5L.SE
+ name_canon_rules = qualify:domain=test2.h5l.se:realm=TEST2.H5L.SE
+ name_canon_rules = qualify:domain=test3.h5l.se:realm=TEST3.H5L.SE
+
+[appdefaults]
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ reconnect-min = 2s
+ reconnect-backoff = 2s
+ reconnect-max = 10s
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ admin_server = localhost:@admport@
+ kpasswd_server = localhost:@pwport@
+ }
+ TEST2.H5L.SE = {
+ kdc = localhost:@port@
+ kpasswd_server = localhost:@pwport@
+ }
+ TEST3.H5L.SE = {
+ kdc = localhost:@port@
+ }
+
+[domain_realm]
+ .test1.h5l.se = TEST.H5L.SE
+ .test2.h5l.se = TEST2.H5L.SE
+ .test3.h5l.se = TEST3.H5L.SE
+ localhost = TEST.H5L.SE
+
+
+[kdc]
+ enable-digest = true
+ allow-anonymous = true
+ digests_allowed = chap-md5,digest-md5,ntlm-v1,ntlm-v1-session,ntlm-v2,ms-chap-v2
+ strict-nametypes = true
+
+ enable-http = true
+
+ enable-pkinit = true
+ pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ pkinit_pool = FILE:@srcdir@/../../lib/hx509/data/sub-ca.crt
+# pkinit_revoke = CRL:@srcdir@/../../lib/hx509/data/crl1.crl
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_allow_proxy_certificate = true
+
+ database = {
+ label = {
+ dbname = @objdir@/current-db@kdc@
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ label2 = {
+ dbname = @objdir@/current-db@kdc@
+ realm = TEST2.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ }
+
+ signal_socket = @objdir@/signal
+ iprop-stats = @objdir@/iprop-stats
+ iprop-acl = @srcdir@/iprop-acl
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+[kadmin]
+ save-password = true
+ @dk@
+
+[capaths]
+ TEST.H5L.SE = {
+ TEST3.H5L.SE = .
+ TEST2.H5L.SE = .
+ }
+ TEST2.H5L.SE = {
+ TEST.H5L.SE = .
+ TEST3.H5L.SE = .
+ }
+ TEST3.H5L.SE = {
+ TEST.H5L.SE = .
+ TEST2.H5L.SE = .
+ }
diff --git a/third_party/heimdal/tests/kdc/krb5-canon2.conf.in b/third_party/heimdal/tests/kdc/krb5-canon2.conf.in
new file mode 100644
index 0000000..dae71d3
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-canon2.conf.in
@@ -0,0 +1,97 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE TEST2.H5L.SE
+ no-addresses = TRUE
+ dns_lookup_realm = no
+ name_canon_rules = as-is:realm=TEST.H5L.SE
+ name_canon_rules = as-is:realm=TEST2.H5L.SE
+ name_canon_rules = as-is:realm=TEST3.H5L.SE
+ name_canon_rules = nss
+
+[appdefaults]
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ reconnect-min = 2s
+ reconnect-backoff = 2s
+ reconnect-max = 10s
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ admin_server = localhost:@admport@
+ kpasswd_server = localhost:@pwport@
+ }
+ TEST2.H5L.SE = {
+ kdc = localhost:@port@
+ kpasswd_server = localhost:@pwport@
+ }
+ TEST3.H5L.SE = {
+ kdc = localhost:@port@
+ }
+
+[domain_realm]
+ .test1.h5l.se = TEST.H5L.SE
+ .test2.h5l.se = TEST2.H5L.SE
+ .test3.h5l.se = TEST3.H5L.SE
+ localhost = TEST.H5L.SE
+
+
+[kdc]
+ enable-digest = true
+ allow-anonymous = true
+ digests_allowed = chap-md5,digest-md5,ntlm-v1,ntlm-v1-session,ntlm-v2,ms-chap-v2
+ strict-nametypes = true
+
+ enable-http = true
+
+ enable-pkinit = true
+ pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ pkinit_pool = FILE:@srcdir@/../../lib/hx509/data/sub-ca.crt
+# pkinit_revoke = CRL:@srcdir@/../../lib/hx509/data/crl1.crl
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_allow_proxy_certificate = true
+
+ database = {
+ label = {
+ dbname = @objdir@/current-db@kdc@
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ label2 = {
+ dbname = @objdir@/current-db@kdc@
+ realm = TEST2.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ }
+
+ signal_socket = @objdir@/signal
+ iprop-stats = @objdir@/iprop-stats
+ iprop-acl = @srcdir@/iprop-acl
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+[kadmin]
+ save-password = true
+ @dk@
+
+[capaths]
+ TEST.H5L.SE = {
+ TEST3.H5L.SE = .
+ TEST2.H5L.SE = .
+ }
+ TEST2.H5L.SE = {
+ TEST.H5L.SE = .
+ TEST3.H5L.SE = .
+ }
+ TEST3.H5L.SE = {
+ TEST.H5L.SE = .
+ TEST2.H5L.SE = .
+ }
diff --git a/third_party/heimdal/tests/kdc/krb5-cccol.conf.in b/third_party/heimdal/tests/kdc/krb5-cccol.conf.in
new file mode 100644
index 0000000..819de80
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-cccol.conf.in
@@ -0,0 +1,165 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE TEST2.H5L.SE
+ default_cc_collection = DIR:@objdir@/cc_dir/
+ no-addresses = TRUE
+ allow_weak_crypto = @WEAK@
+ dns_lookup_kdc = no
+ dns_lookup_realm = no
+
+
+[appdefaults]
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ reconnect-min = 2s
+ reconnect-backoff = 2s
+ reconnect-max = 10s
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ admin_server = localhost:@admport@
+ kpasswd_server = localhost:@pwport@
+ }
+ SUB.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ TEST2.H5L.SE = {
+ kdc = localhost:@port@
+ kpasswd_server = localhost:@pwport@
+ }
+ TEST3.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ TEST4.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM5.FR = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM6.US = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM7.UK = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM8.UK = {
+ kdc = localhost:@port@
+ }
+ TEST-HTTP.H5L.SE = {
+ kdc = http/localhost:@port@
+ }
+ H1.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ H2.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ H3.H2.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ H4.H2.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+
+[domain_realm]
+ .test.h5l.se = TEST.H5L.SE
+ .sub.test.h5l.se = SUB.TEST.H5L.SE
+ .h1.test.h5l.se = H1.TEST.H5L.SE
+ .h2.test.h5l.se = H2.TEST.H5L.SE
+ .h3.h2.test.h5l.se = H3.H2.TEST.H5L.SE
+ .h4.h2.test.h5l.se = H4.H2.TEST.H5L.SE
+ .example.com = TEST2.H5L.SE
+ localhost = TEST.H5L.SE
+ .localdomain = TEST.H5L.SE
+ localdomain = TEST.H5L.SE
+ .localdomain6 = TEST.H5L.SE
+ localdomain6 = TEST.H5L.SE
+
+
+[kdc]
+ enable-digest = true
+ allow-anonymous = true
+ digests_allowed = chap-md5,digest-md5,ntlm-v1,ntlm-v1-session,ntlm-v2,ms-chap-v2
+ strict-nametypes = true
+
+ enable-http = true
+
+ enable-pkinit = true
+ pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ pkinit_pool = FILE:@srcdir@/../../lib/hx509/data/sub-ca.crt
+# pkinit_revoke = CRL:@srcdir@/../../lib/hx509/data/crl1.crl
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_allow_proxy_certificate = true
+
+ database = {
+ label = {
+ dbname = @db_type@:@objdir@/current-db@kdc@
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ label2 = {
+ dbname = @db_type@:@objdir@/current-db@kdc@
+ realm = TEST2.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ label3 = {
+ dbname = sqlite:@objdir@/current-db@kdc@.sqlite3
+ realm = SOME-REALM5.FR
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ }
+
+ signal_socket = @objdir@/signal
+ iprop-stats = @objdir@/iprop-stats
+ iprop-acl = @srcdir@/iprop-acl
+ log-max-size = 40000
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ krb5 = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+# If you are doing preformance measurements on OSX you want to change
+# the kdc LOG line from = to - below to keep the FILE open and avoid
+# open/write/close which is blocking (rdar:// ) on OSX.
+# kdc = 0-/FILE=@objdir@/messages.log
+
+[kadmin]
+ save-password = true
+ default_key_rules = {
+ */des3-only@* = des3-cbc-sha1:pw-salt
+ */aes-only@* = aes256-cts-hmac-sha1-96:pw-salt
+ }
+ @dk@
+
+[capaths]
+ TEST.H5L.SE = {
+ TEST2.H5L.SE = .
+ SOME-REALM5.FR = 1
+ TEST3.H5L.SE = TEST2.H5L.SE
+ TEST4.H5L.SE = TEST2.H5L.SE
+ TEST4.H5L.SE = TEST3.H5L.SE
+ SOME-REALM6.US = SOME-REALM5.FR
+ SOME-REALM7.UK = SOME-REALM6.US
+ SOME-REALM7.UK = SOME-REALM5.FR
+ SOME-REALM8.UK = SOME-REALM6.US
+ }
+ H4.H2.TEST.H5L.SE = {
+ H1.TEST.H5L.SE = H3.H2.TEST.H5L.SE
+ H1.TEST.H5L.SE = H2.TEST.H5L.SE
+ H1.TEST.H5L.SE = TEST.H5L.SE
+
+ TEST.H5L.SE = H3.H2.TEST.H5L.SE
+ TEST.H5L.SE = H2.TEST.H5L.SE
+
+ H2.TEST.H5L.SE = H3.H2.TEST.H5L.SE
+ }
diff --git a/third_party/heimdal/tests/kdc/krb5-hdb-mitdb.conf.in b/third_party/heimdal/tests/kdc/krb5-hdb-mitdb.conf.in
new file mode 100644
index 0000000..2be7eed
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-hdb-mitdb.conf.in
@@ -0,0 +1,60 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE TEST2.H5L.SE
+ no-addresses = TRUE
+ allow_weak_crypto = TRUE
+
+[appdefaults]
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ reconnect-min = 2s
+ reconnect-backoff = 2s
+ reconnect-max = 10s
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ admin_server = localhost:@admport@
+ kpasswd_server = localhost:@pwport@
+ }
+
+[domain_realm]
+ .test.h5l.se = TEST.H5L.SE
+ localhost = TEST.H5L.SE
+
+[kdc]
+ enable-digest = true
+ allow-anonymous = true
+ digests_allowed = chap-md5,digest-md5,ntlm-v1,ntlm-v1-session,ntlm-v2,ms-chap-v2
+ strict-nametypes = true
+
+ enable-http = true
+
+ enable-pkinit = true
+ pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ pkinit_pool = FILE:@srcdir@/../../lib/hx509/data/sub-ca.crt
+# pkinit_revoke = CRL:@srcdir@/../../lib/hx509/data/crl1.crl
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_allow_proxy_certificate = true
+
+ database = {
+ label = {
+ dbname = mit-db:@srcdir@/hdb-mitdb
+ realm = TEST.H5L.SE
+ mkey_file = @srcdir@/hdb-mitdb.mkey
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ }
+
+ signal_socket = @objdir@/signal
+ iprop-stats = @objdir@/iprop-stats
+ iprop-acl = @srcdir@/iprop-acl
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+[kadmin]
+ save-password = true
+ @dk@
+
diff --git a/third_party/heimdal/tests/kdc/krb5-httpkadmind.conf.in b/third_party/heimdal/tests/kdc/krb5-httpkadmind.conf.in
new file mode 100644
index 0000000..fb2fc6a
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-httpkadmind.conf.in
@@ -0,0 +1,98 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE
+ no-addresses = TRUE
+ allow_weak_crypto = TRUE
+ rdns = false
+ fcache_strict_checking = false
+ name_canon_rules = as-is:realm=TEST.H5L.SE
+
+[appdefaults]
+ pkinit_anchors = FILE:@objdir@/ca.crt
+ pkinit_pool = FILE:@objdir@/ca.crt
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ pkinit_win2k = @w2k@
+ }
+
+[kdc]
+ num-kdc-processes = 1
+ strict-nametypes = true
+ synthetic_clients = true
+ enable-pkinit = true
+ pkinit_identity = FILE:@objdir@/kdc.crt,@srcdir@/../../lib/hx509/data/key2.der
+ pkinit_anchors = FILE:@objdir@/ca.crt
+ pkinit_mappings_file = @srcdir@/pki-mapping
+
+ # Locate kdc plugins for testing
+ plugin_dir = @objdir@/../../kdc/.libs
+
+ database = {
+ dbname = @objdir@/current-db
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ log_file = @objdir@/log.current-db.log
+ acl_file = @srcdir@/heimdal.acl
+ }
+
+ negotiate_token_validator = {
+ keytab = FILE:@objdir@/kt
+ }
+
+ realms = {
+ TEST.H5L.SE = {
+ kx509 = {
+ user = {
+ include_pkinit_san = true
+ subject_name = CN=${principal-name-without-realm},DC=test,DC=h5l,DC=se
+ ekus = 1.3.6.1.5.5.7.3.2
+ ca = PEM-FILE:@objdir@/user-issuer.pem
+ }
+ hostbased_service = {
+ HTTP = {
+ include_dnsname_san = true
+ ekus = 1.3.6.1.5.5.7.3.1
+ ca = PEM-FILE:@objdir@/server-issuer.pem
+ }
+ }
+ client = {
+ ekus = 1.3.6.1.5.5.7.3.2
+ ca = PEM-FILE:@objdir@/user-issuer.pem
+ }
+ server = {
+ ekus = 1.3.6.1.5.5.7.3.1
+ ca = PEM-FILE:@objdir@/server-issuer.pem
+ }
+ mixed = {
+ ekus = 1.3.6.1.5.5.7.3.1
+ ekus = 1.3.6.1.5.5.7.3.2
+ ca = PEM-FILE:@objdir@/mixed-issuer.pem
+ }
+ }
+ }
+ }
+
+[hdb]
+ db-dir = @objdir@
+ enable_virtual_hostbased_princs = true
+ virtual_hostbased_princ_mindots = 1
+ virtual_hostbased_princ_maxdots = 3
+ virtual_hostbased_princ_svcs = HTTP host
+
+[ext_keytab]
+ new_hostbased_service_principal_attributes = {
+ host = {
+ a-particular-hostname.test.h5l.se = ok-as-delegate,no-auth-data-reqd
+ .prod.test.h5l.se = ok-as-delegate no-auth-data-reqd
+ }
+ }
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ bx509d = 0-/FILE:@objdir@/messages.log
+ httpkadmind = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+[domain_realm]
+ . = TEST.H5L.SE
diff --git a/third_party/heimdal/tests/kdc/krb5-kcm.conf.in b/third_party/heimdal/tests/kdc/krb5-kcm.conf.in
new file mode 100644
index 0000000..bdcca07
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-kcm.conf.in
@@ -0,0 +1,165 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE TEST2.H5L.SE
+ default_ccache_name = KCM:%{uid}
+ no-addresses = TRUE
+ allow_weak_crypto = @WEAK@
+ dns_lookup_kdc = no
+ dns_lookup_realm = no
+
+
+[appdefaults]
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ reconnect-min = 2s
+ reconnect-backoff = 2s
+ reconnect-max = 10s
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ admin_server = localhost:@admport@
+ kpasswd_server = localhost:@pwport@
+ }
+ SUB.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ TEST2.H5L.SE = {
+ kdc = localhost:@port@
+ kpasswd_server = localhost:@pwport@
+ }
+ TEST3.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ TEST4.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM5.FR = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM6.US = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM7.UK = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM8.UK = {
+ kdc = localhost:@port@
+ }
+ TEST-HTTP.H5L.SE = {
+ kdc = http/localhost:@port@
+ }
+ H1.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ H2.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ H3.H2.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ H4.H2.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+
+[domain_realm]
+ .test.h5l.se = TEST.H5L.SE
+ .sub.test.h5l.se = SUB.TEST.H5L.SE
+ .h1.test.h5l.se = H1.TEST.H5L.SE
+ .h2.test.h5l.se = H2.TEST.H5L.SE
+ .h3.h2.test.h5l.se = H3.H2.TEST.H5L.SE
+ .h4.h2.test.h5l.se = H4.H2.TEST.H5L.SE
+ .example.com = TEST2.H5L.SE
+ localhost = TEST.H5L.SE
+ .localdomain = TEST.H5L.SE
+ localdomain = TEST.H5L.SE
+ .localdomain6 = TEST.H5L.SE
+ localdomain6 = TEST.H5L.SE
+
+
+[kdc]
+ enable-digest = true
+ allow-anonymous = true
+ digests_allowed = chap-md5,digest-md5,ntlm-v1,ntlm-v1-session,ntlm-v2,ms-chap-v2
+ strict-nametypes = true
+
+ enable-http = true
+
+ enable-pkinit = true
+ pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ pkinit_pool = FILE:@srcdir@/../../lib/hx509/data/sub-ca.crt
+# pkinit_revoke = CRL:@srcdir@/../../lib/hx509/data/crl1.crl
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_allow_proxy_certificate = true
+
+ database = {
+ label = {
+ dbname = @db_type@:@objdir@/current-db@kdc@
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ label2 = {
+ dbname = @db_type@:@objdir@/current-db@kdc@
+ realm = TEST2.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ label3 = {
+ dbname = sqlite:@objdir@/current-db@kdc@.sqlite3
+ realm = SOME-REALM5.FR
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ }
+
+ signal_socket = @objdir@/signal
+ iprop-stats = @objdir@/iprop-stats
+ iprop-acl = @srcdir@/iprop-acl
+ log-max-size = 40000
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ krb5 = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+# If you are doing preformance measurements on OSX you want to change
+# the kdc LOG line from = to - below to keep the FILE open and avoid
+# open/write/close which is blocking (rdar:// ) on OSX.
+# kdc = 0-/FILE=@objdir@/messages.log
+
+[kadmin]
+ save-password = true
+ default_key_rules = {
+ */des3-only@* = des3-cbc-sha1:pw-salt
+ */aes-only@* = aes256-cts-hmac-sha1-96:pw-salt
+ }
+ @dk@
+
+[capaths]
+ TEST.H5L.SE = {
+ TEST2.H5L.SE = .
+ SOME-REALM5.FR = 1
+ TEST3.H5L.SE = TEST2.H5L.SE
+ TEST4.H5L.SE = TEST2.H5L.SE
+ TEST4.H5L.SE = TEST3.H5L.SE
+ SOME-REALM6.US = SOME-REALM5.FR
+ SOME-REALM7.UK = SOME-REALM6.US
+ SOME-REALM7.UK = SOME-REALM5.FR
+ SOME-REALM8.UK = SOME-REALM6.US
+ }
+ H4.H2.TEST.H5L.SE = {
+ H1.TEST.H5L.SE = H3.H2.TEST.H5L.SE
+ H1.TEST.H5L.SE = H2.TEST.H5L.SE
+ H1.TEST.H5L.SE = TEST.H5L.SE
+
+ TEST.H5L.SE = H3.H2.TEST.H5L.SE
+ TEST.H5L.SE = H2.TEST.H5L.SE
+
+ H2.TEST.H5L.SE = H3.H2.TEST.H5L.SE
+ }
diff --git a/third_party/heimdal/tests/kdc/krb5-pkinit.conf.in b/third_party/heimdal/tests/kdc/krb5-pkinit.conf.in
new file mode 100644
index 0000000..e2d3f3d
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5-pkinit.conf.in
@@ -0,0 +1,82 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE
+ no-addresses = TRUE
+ allow_weak_crypto = TRUE
+ enable_kx509 = true
+
+[appdefaults]
+ pkinit_anchors = FILE:@objdir@/ca.crt
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ pkinit_win2k = @w2k@
+ }
+
+[kdc]
+ strict-nametypes = true
+ synthetic_clients = true
+ enable-pkinit = true
+ pkinit_identity = FILE:@objdir@/kdc.crt,@srcdir@/../../lib/hx509/data/key2.der
+ pkinit_anchors = FILE:@objdir@/ca.crt
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_max_life_from_cert_extension = true
+ pkinit_max_life_from_cert = @max_life_from_cert@
+
+ plugin_dir = @objdir@/../../kdc/.libs
+
+ ipc_csr_authorizer = {
+ optional = true
+ }
+
+ enable_kx509 = true
+ require_initial_kca_tickets = false
+
+ database = {
+ dbname = @objdir@/current-db
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ log_file = @objdir@/log.current-db.log
+ }
+
+
+ realms = {
+ TEST.H5L.SE = {
+ negotiate_token_validator = {
+ keytab = HDBGET:@objdir@/current-db
+ }
+ kx509 = {
+ user = {
+ include_pkinit_san = true
+ subject_name = CN=${principal-name-without-realm},DC=TEST,DC=H5L,DC=SE
+ ekus = 1.3.6.1.5.5.7.3.2
+ ca = FILE:@objdir@/ca.crt,@srcdir@/../../lib/hx509/data/key.der
+ template_cert = FILE:@objdir@/kx509-template.crt
+ }
+ hostbased_service = {
+ HTTP = {
+ include_dnsname_san = true
+ ekus = 1.3.6.1.5.5.7.3.1
+ ca = FILE:@objdir@/ca.crt,@srcdir@/../../lib/hx509/data/key.der
+ }
+ }
+ client = {
+ ca = FILE:@objdir@/ca.crt,@srcdir@/../../lib/hx509/data/key.der
+ }
+ server = {
+ ekus = 1.3.6.1.5.5.7.3.1
+ ca = FILE:@objdir@/ca.crt,@srcdir@/../../lib/hx509/data/key.der
+ }
+ }
+ }
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+[kadmin]
+ save-password = true
diff --git a/third_party/heimdal/tests/kdc/krb5.conf.in b/third_party/heimdal/tests/kdc/krb5.conf.in
new file mode 100644
index 0000000..5b9d644
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5.conf.in
@@ -0,0 +1,175 @@
+[libdefaults]
+ default_realm = TEST.H5L.SE TEST2.H5L.SE
+ no-addresses = TRUE
+ allow_weak_crypto = @WEAK@
+ dns_lookup_kdc = no
+ dns_lookup_realm = no
+
+
+[appdefaults]
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ reconnect-min = 2s
+ reconnect-backoff = 2s
+ reconnect-max = 10s
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ admin_server = localhost:@admport@
+ kpasswd_server = localhost:@pwport@
+ }
+ SUB.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ TEST2.H5L.SE = {
+ kdc = localhost:@port@
+ kpasswd_server = localhost:@pwport@
+ }
+ TEST3.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ TEST4.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ XTST.HEIM.EXAMPLE = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM5.FR = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM6.US = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM7.UK = {
+ kdc = localhost:@port@
+ }
+ SOME-REALM8.UK = {
+ kdc = localhost:@port@
+ }
+ TEST-HTTP.H5L.SE = {
+ kdc = http/localhost:@port@
+ }
+ H1.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ H2.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ H3.H2.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ H4.H2.TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+
+[domain_realm]
+ .test.h5l.se = TEST.H5L.SE
+ .sub.test.h5l.se = SUB.TEST.H5L.SE
+ .h1.test.h5l.se = H1.TEST.H5L.SE
+ .h2.test.h5l.se = H2.TEST.H5L.SE
+ .h3.h2.test.h5l.se = H3.H2.TEST.H5L.SE
+ .h4.h2.test.h5l.se = H4.H2.TEST.H5L.SE
+ .example.com = TEST2.H5L.SE
+ localhost = TEST.H5L.SE
+ .localdomain = TEST.H5L.SE
+ localdomain = TEST.H5L.SE
+ .localdomain6 = TEST.H5L.SE
+ localdomain6 = TEST.H5L.SE
+
+
+[kdc]
+ enable-digest = true
+ allow-anonymous = true
+ digests_allowed = chap-md5,digest-md5,ntlm-v1,ntlm-v1-session,ntlm-v2,ms-chap-v2
+ strict-nametypes = true
+
+ enable-http = true
+
+ synthetic_clients = true
+
+ enable_gss_preauth = true
+ gss_mechanisms_allowed = sanon-x25519
+
+ enable-pkinit = true
+ pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ pkinit_pool = FILE:@srcdir@/../../lib/hx509/data/sub-ca.crt
+# pkinit_revoke = CRL:@srcdir@/../../lib/hx509/data/crl1.crl
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_allow_proxy_certificate = true
+
+ database = {
+ label = {
+ dbname = @db_type@:@objdir@/current-db@kdc@
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ label2 = {
+ dbname = @db_type@:@objdir@/current-db@kdc@
+ realm = TEST2.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ label3 = {
+ dbname = sqlite:@objdir@/current-db@kdc@.sqlite3
+ realm = SOME-REALM5.FR
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/current@kdc@.log
+ }
+ }
+
+ signal_socket = @objdir@/@signalsocket@
+ iprop-stats = @objdir@/@ipropstats@
+ iprop-acl = @srcdir@/iprop-acl
+ log-max-size = 40000
+
+[hdb]
+ db-dir = @objdir@
+ enable_virtual_hostbased_princs = true
+ virtual_hostbased_princ_mindots = 1
+ virtual_hostbased_princ_maxdots = 3
+
+[logging]
+ kdc = 0-/FILE:@objdir@/@messages@.log
+ krb5 = 0-/FILE:@objdir@/@messages@.log
+ default = 0-/FILE:@objdir@/@messages@.log
+
+# If you are doing preformance measurements on OSX you want to change
+# the kdc LOG line from = to - below to keep the FILE open and avoid
+# open/write/close which is blocking (rdar:// ) on OSX.
+# kdc = 0-/FILE=@objdir@/@messages@.log
+
+[kadmin]
+ save-password = true
+ default_key_rules = {
+ */des3-only@* = des3-cbc-sha1:pw-salt
+ */aes-only@* = aes256-cts-hmac-sha1-96:pw-salt
+ }
+ @dk@
+
+[capaths]
+ TEST.H5L.SE = {
+ TEST2.H5L.SE = .
+ SOME-REALM5.FR = 1
+ TEST3.H5L.SE = TEST2.H5L.SE
+ TEST4.H5L.SE = TEST2.H5L.SE
+ TEST4.H5L.SE = TEST3.H5L.SE
+ SOME-REALM6.US = SOME-REALM5.FR
+ SOME-REALM7.UK = SOME-REALM6.US
+ SOME-REALM7.UK = SOME-REALM5.FR
+ SOME-REALM8.UK = SOME-REALM6.US
+ }
+ H4.H2.TEST.H5L.SE = {
+ H1.TEST.H5L.SE = H3.H2.TEST.H5L.SE
+ H1.TEST.H5L.SE = H2.TEST.H5L.SE
+ H1.TEST.H5L.SE = TEST.H5L.SE
+
+ TEST.H5L.SE = H3.H2.TEST.H5L.SE
+ TEST.H5L.SE = H2.TEST.H5L.SE
+
+ H2.TEST.H5L.SE = H3.H2.TEST.H5L.SE
+ }
diff --git a/third_party/heimdal/tests/kdc/krb5.conf.keys.in b/third_party/heimdal/tests/kdc/krb5.conf.keys.in
new file mode 100644
index 0000000..16891de
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/krb5.conf.keys.in
@@ -0,0 +1,19 @@
+[libdefaults]
+ allow_weak_crypto = TRUE
+
+[kdc]
+ strict-nametypes = true
+ database = {
+ dbname = @objdir@/current-db
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ acl_file = @srcdir@/heimdal.acl
+ log_file = @objdir@/log.current-db.log
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+
+[kadmin]
+ default_keys = @keys@
diff --git a/third_party/heimdal/tests/kdc/leaks-kill.sh b/third_party/heimdal/tests/kdc/leaks-kill.sh
new file mode 100644
index 0000000..1474bdd
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/leaks-kill.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+name=$1
+pid=$2
+
+kill $pid
+set -- .
+while kill -0 $pid 2>/dev/null
+do
+ set -- "$@" "."
+ if [ $# -gt 4 ]
+ then
+ kill kill -9 $pid 2> /dev/null
+ break
+ fi
+ sleep 1
+done
+
+set -- .
+while kill -0 $pid 2>/dev/null
+do
+ set -- "$@" "."
+ if [ $# -gt 4 ]; then exit 1; fi
+ sleep 1
+done
+
+exit 0
diff --git a/third_party/heimdal/tests/kdc/ntlm-user-file.txt b/third_party/heimdal/tests/kdc/ntlm-user-file.txt
new file mode 100644
index 0000000..d807127
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/ntlm-user-file.txt
@@ -0,0 +1 @@
+TEST:foo:digestpassword
diff --git a/third_party/heimdal/tests/kdc/pki-mapping b/third_party/heimdal/tests/kdc/pki-mapping
new file mode 100644
index 0000000..18fb481
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/pki-mapping
@@ -0,0 +1,2 @@
+foo@TEST.H5L.SE:CN=pkinit,C=SE
+foo@TEST.H5L.SE:CN=bar,DC=test,DC=h5l,DC=se
diff --git a/third_party/heimdal/tests/kdc/uuserver.txt b/third_party/heimdal/tests/kdc/uuserver.txt
new file mode 100644
index 0000000..2c191bf
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/uuserver.txt
@@ -0,0 +1,4 @@
+User is `user2@TEST.H5L.SE'
+Server is `user1@TEST.H5L.SE'
+safe packet: hej
+priv packet: hemligt
diff --git a/third_party/heimdal/tests/kdc/wait-kdc.sh b/third_party/heimdal/tests/kdc/wait-kdc.sh
new file mode 100644
index 0000000..d0226fc
--- /dev/null
+++ b/third_party/heimdal/tests/kdc/wait-kdc.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+name=${1:-KDC}
+log=${2:-messages.log}
+waitfor="${3:-${name} started}"
+
+t=0
+waitsec=65
+
+echo "Waiting for ${name} to start, see logfile ${log}"
+
+while true ; do
+ if grep "${waitfor}" ${log} > /dev/null; then
+ break
+ fi
+ if grep "No sockets" ${log} ; then
+ echo "The ${name} failed to bind to any sockets, another ${name} running ?"
+ exit 1
+ fi
+ if grep "bind" ${log} | grep "Operation not permitted" ; then
+ echo "The ${name} failed to bind to any sockets, another ${name} running ?"
+ exit 1
+ fi
+ if [ "$t" -gt $waitsec ]; then
+ echo "Error: ${name} failed to start after $waitsec seconds"
+ exit 2
+ fi
+
+ t=`expr ${t} + 2`
+ sleep 2
+ echo "Have waited $t seconds"
+done
+
+exit 0
diff --git a/third_party/heimdal/tests/ldap/Makefile.am b/third_party/heimdal/tests/ldap/Makefile.am
new file mode 100644
index 0000000..cbc0b7d
--- /dev/null
+++ b/third_party/heimdal/tests/ldap/Makefile.am
@@ -0,0 +1,55 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+noinst_DATA = krb5.conf
+
+check_SCRIPTS = $(TESTS) slapd-init
+
+TESTS = check-ldap
+
+port = 49188
+
+do_subst = sed \
+ -e 's,[@]env_setup[@],$(top_builddir)/tests/bin/setup-env,g' \
+ -e 's,[@]srcdir[@],$(srcdir),g' \
+ -e 's,[@]port[@],$(port),g' \
+ -e 's,[@]objdir[@],$(top_builddir)/tests/ldap,g' \
+ -e 's,[@]EGREP[@],$(EGREP),g'
+
+check-ldap: check-ldap.in Makefile
+ $(do_subst) < $(srcdir)/check-ldap.in > check-ldap.tmp
+ chmod +x check-ldap.tmp
+ mv check-ldap.tmp check-ldap
+
+slapd-init: slapd-init.in Makefile
+ $(do_subst) < $(srcdir)/slapd-init.in > slapd-init.tmp
+ chmod +x slapd-init.tmp
+ mv slapd-init.tmp slapd-init
+
+krb5.conf: krb5.conf.in Makefile
+ $(do_subst) < $(srcdir)/krb5.conf.in > krb5.conf.tmp
+ mv krb5.conf.tmp krb5.conf
+
+CLEANFILES= \
+ $(TESTS) \
+ check-ldap.tmp \
+ slapd-init.tmp \
+ current-db* \
+ krb5.conf krb5.conf.tmp \
+ modules.conf \
+ cache.krb5 \
+ slapd-init \
+ foopassword \
+ messages.log \
+ slapd.pid
+
+EXTRA_DIST = \
+ NTMakefile \
+ samba.schema \
+ slapd.conf \
+ slapd-stop \
+ check-ldap.in \
+ init.ldif \
+ krb5.conf.in \
+ slapd-init.in
diff --git a/third_party/heimdal/tests/ldap/NTMakefile b/third_party/heimdal/tests/ldap/NTMakefile
new file mode 100644
index 0000000..9c5de09
--- /dev/null
+++ b/third_party/heimdal/tests/ldap/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=tests\ldap
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/tests/ldap/check-ldap.in b/third_party/heimdal/tests/ldap/check-ldap.in
new file mode 100644
index 0000000..f73eb6e
--- /dev/null
+++ b/third_party/heimdal/tests/ldap/check-ldap.in
@@ -0,0 +1,153 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2016 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+env_setup="@env_setup@"
+srcdir="@srcdir@"
+objdir="@objdir@"
+
+. ${env_setup}
+
+EGREP="@EGREP@"
+
+R=TEST.H5L.SE
+
+port=@port@
+
+server=host/datan.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+
+kinit="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cache ${afs_no_afslog}"
+kgetcred="${TESTS_ENVIRONMENT} ../../kuser/kgetcred -c $cache"
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r $R"
+kdc="${TESTS_ENVIRONMENT} ../../kdc/kdc --addresses=localhost -P $port"
+
+foopassword="fooLongPasswordYo123;"
+
+testfailed="echo test failed; exit 1"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+# If there is no ldap support compiled in, disable test
+if ${kdc} --builtin-hdb | grep ldap > /dev/null ; then
+ :
+else
+ echo "no ldap support"
+ exit 77
+fi
+
+#search for all ldap tools
+
+PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/libexec:/usr/lib/openldap:$PATH
+export PATH
+
+oldifs=$IFS
+IFS=:
+set -- $PATH
+IFS=$oldifs
+for j in slapd slapadd; do
+ for i in $*; do
+ test -n "$i" || i="."
+ if test -x $i/$j; then
+ continue 2
+ fi
+ done
+ echo "$j missing, not running test"
+ exit 77
+done
+
+sh ${objdir}/slapd-init || exit 1
+
+trap "sh ${srcdir}/slapd-stop ; exit 1;" EXIT
+
+rm -f current-db*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p "$foopassword" --use-defaults foo@${R} || exit 1
+${kadmin} add -p "$foopassword" --use-defaults bar@${R} || exit 1
+${kadmin} add -p kaka --use-defaults ${server}@${R} || exit 1
+
+${kadmin} cpw --random-password bar@${R} > /dev/null || exit 1
+${kadmin} cpw --random-password bar@${R} > /dev/null || exit 1
+${kadmin} cpw --random-password bar@${R} > /dev/null || exit 1
+
+${kadmin} cpw --random-password suser@${R} > /dev/null|| exit 1
+${kadmin} cpw --password="$foopassword" suser@${R} || exit 1
+
+${kadmin} list '*' > /dev/null || exit 1
+
+echo "$foopassword" > ${objdir}/foopassword
+
+echo Starting kdc
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill ${kdcpid}; echo signal killing kdc; sh ${srcdir}/slapd-stop ; exit 1;" EXIT
+
+ec=0
+
+echo "Getting client initial tickets";
+${kinit} --password-file=${objdir}/foopassword foo@$R || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting ${server} ticket"
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+
+
+echo "Getting *@$R initial ticket (fail)";
+${kinit} --password-file=${objdir}/foopassword '*'@$R 2>/dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+
+echo "killing kdc (${kdcpid})"
+kill $kdcpid || exit 1
+
+trap "" EXIT
+
+# kill of old slapd
+sh ${srcdir}/slapd-stop
+
+rm -rf db schema
+
+exit $ec
diff --git a/third_party/heimdal/tests/ldap/init.ldif b/third_party/heimdal/tests/ldap/init.ldif
new file mode 100644
index 0000000..371702f
--- /dev/null
+++ b/third_party/heimdal/tests/ldap/init.ldif
@@ -0,0 +1,44 @@
+dn: o=TEST,dc=H5L,dc=SE
+objectclass: organization
+o: Test
+
+dn: ou=kerberosPrincipals,o=TEST,dc=H5L,dc=SE
+objectclass: organizationalUnit
+ou: kerberosPrincipals
+
+dn: uid=suser,ou=kerberosPrincipals,o=TEST,dc=H5L,dc=SE
+cn: root
+sn: root
+objectClass: inetOrgPerson
+objectClass: posixAccount
+objectClass: organizationalPerson
+objectClass: person
+objectClass: top
+gidNumber: 0
+uid: suser
+uidNumber: 0
+homeDirectory: /root
+loginShell: /bin/bash
+gecos: Netbios root user
+structuralObjectClass: inetOrgPerson
+creatorsName: cn=root,dc=test,dc=h5l,dc=se
+userPassword: password
+objectClass: krb5KDCEntry
+krb5KeyVersionNumber: 2
+krb5PrincipalName: suser@TEST.H5L.SE
+objectClass: sambaSamAccount
+sambaHomePath: \\admin1\suser
+sambaPwdCanChange: 1159699688
+sambaPwdLastSet: 1159699688
+sambaPrimaryGroupSID: S-1-5-21-3017333096-1338036268-1966094567-512
+sambaPasswordHistory: 00000000000000000000000000000000000000000000000000000000
+ 00000000
+sambaLMPassword: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+sambaNTPassword: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+sambaLogonTime: 0
+sambaLogoffTime: 2147483647
+sambaKickoffTime: 2147483647
+sambaPwdMustChange: 2147483647
+sambaHomeDrive: H:
+sambaAcctFlags: [U ]
+sambaSID: S-1-5-21-3017333096-1338036268-1966094567-1000
diff --git a/third_party/heimdal/tests/ldap/krb5.conf.in b/third_party/heimdal/tests/ldap/krb5.conf.in
new file mode 100644
index 0000000..e5f1a17
--- /dev/null
+++ b/third_party/heimdal/tests/ldap/krb5.conf.in
@@ -0,0 +1,26 @@
+# $Id$
+
+[libdefaults]
+ default_realm = TEST.H5L.SE
+ no-addresses = TRUE
+ plugin_dir = @objdir@/../../lib/hdb @objdir@/../../lib/hdb/.libs
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+
+[kdc]
+ database = {
+ dbname = ldapi://.%2Fldap-socket:OU=KerberosPrincipals,o=test,DC=h5l,DC=se
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ log_file = @objdir@/log.current-db.log
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
diff --git a/third_party/heimdal/tests/ldap/samba.schema b/third_party/heimdal/tests/ldap/samba.schema
new file mode 100644
index 0000000..549a708
--- /dev/null
+++ b/third_party/heimdal/tests/ldap/samba.schema
@@ -0,0 +1,554 @@
+##
+## schema file for OpenLDAP 2.x
+## Schema for storing Samba user accounts and group maps in LDAP
+## OIDs are owned by the Samba Team
+##
+## Prerequisite schemas - uid (cosine.schema)
+## - displayName (inetorgperson.schema)
+## - gidNumber (nis.schema)
+##
+## 1.3.6.1.4.1.7165.2.1.x - attributetypes
+## 1.3.6.1.4.1.7165.2.2.x - objectclasses
+##
+## Printer support
+## 1.3.6.1.4.1.7165.2.3.1.x - attributetypes
+## 1.3.6.1.4.1.7165.2.3.2.x - objectclasses
+##
+## Samba4
+## 1.3.6.1.4.1.7165.4.1.x - attributetypes
+## 1.3.6.1.4.1.7165.4.2.x - objectclasses
+## 1.3.6.1.4.1.7165.4.3.x - LDB/LDAP Controls
+## 1.3.6.1.4.1.7165.4.4.x - LDB/LDAP Extended Operations
+## 1.3.6.1.4.1.7165.4.255.x - mapped OIDs due to conflicts between AD and standards-track
+##
+## ----- READ THIS WHEN ADDING A NEW ATTRIBUTE OR OBJECT CLASS ------
+##
+## Run the 'get_next_oid' bash script in this directory to find the
+## next available OID for attribute type and object classes.
+##
+## $ ./get_next_oid
+## attributetype ( 1.3.6.1.4.1.7165.2.1.XX NAME ....
+## objectclass ( 1.3.6.1.4.1.7165.2.2.XX NAME ....
+##
+## Also ensure that new entries adhere to the declaration style
+## used throughout this file
+##
+## <attributetype|objectclass> ( 1.3.6.1.4.1.7165.2.XX.XX NAME ....
+## ^ ^ ^
+##
+## The spaces are required for the get_next_oid script (and for
+## readability).
+##
+## ------------------------------------------------------------------
+
+# objectIdentifier SambaRoot 1.3.6.1.4.1.7165
+# objectIdentifier Samba3 SambaRoot:2
+# objectIdentifier Samba3Attrib Samba3:1
+# objectIdentifier Samba3ObjectClass Samba3:2
+# objectIdentifier Samba4 SambaRoot:4
+
+########################################################################
+## HISTORICAL ##
+########################################################################
+
+##
+## Password hashes
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.1 NAME 'lmPassword'
+# DESC 'LanManager Passwd'
+# EQUALITY caseIgnoreIA5Match
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.2 NAME 'ntPassword'
+# DESC 'NT Passwd'
+# EQUALITY caseIgnoreIA5Match
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+##
+## Account flags in string format ([UWDX ])
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.4 NAME 'acctFlags'
+# DESC 'Account Flags'
+# EQUALITY caseIgnoreIA5Match
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
+
+##
+## Password timestamps & policies
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.3 NAME 'pwdLastSet'
+# DESC 'NT pwdLastSet'
+# EQUALITY integerMatch
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.5 NAME 'logonTime'
+# DESC 'NT logonTime'
+# EQUALITY integerMatch
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.6 NAME 'logoffTime'
+# DESC 'NT logoffTime'
+# EQUALITY integerMatch
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.7 NAME 'kickoffTime'
+# DESC 'NT kickoffTime'
+# EQUALITY integerMatch
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.8 NAME 'pwdCanChange'
+# DESC 'NT pwdCanChange'
+# EQUALITY integerMatch
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.9 NAME 'pwdMustChange'
+# DESC 'NT pwdMustChange'
+# EQUALITY integerMatch
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+##
+## string settings
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.10 NAME 'homeDrive'
+# DESC 'NT homeDrive'
+# EQUALITY caseIgnoreIA5Match
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.11 NAME 'scriptPath'
+# DESC 'NT scriptPath'
+# EQUALITY caseIgnoreIA5Match
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.12 NAME 'profilePath'
+# DESC 'NT profilePath'
+# EQUALITY caseIgnoreIA5Match
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.13 NAME 'userWorkstations'
+# DESC 'userWorkstations'
+# EQUALITY caseIgnoreIA5Match
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{255} SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.17 NAME 'smbHome'
+# DESC 'smbHome'
+# EQUALITY caseIgnoreIA5Match
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.18 NAME 'domain'
+# DESC 'Windows NT domain to which the user belongs'
+# EQUALITY caseIgnoreIA5Match
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{128} )
+
+##
+## user and group RID
+##
+#attributetype ( 1.3.6.1.4.1.7165.2.1.14 NAME 'rid'
+# DESC 'NT rid'
+# EQUALITY integerMatch
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+#attributetype ( 1.3.6.1.4.1.7165.2.1.15 NAME 'primaryGroupID'
+# DESC 'NT Group RID'
+# EQUALITY integerMatch
+# SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+##
+## The smbPasswordEntry objectclass has been depreciated in favor of the
+## sambaAccount objectclass
+##
+#objectclass ( 1.3.6.1.4.1.7165.2.2.1 NAME 'smbPasswordEntry' SUP top AUXILIARY
+# DESC 'Samba smbpasswd entry'
+# MUST ( uid $ uidNumber )
+# MAY ( lmPassword $ ntPassword $ pwdLastSet $ acctFlags ))
+
+#objectclass ( 1.3.6.1.4.1.7165.2.2.2 NAME 'sambaAccount' SUP top STRUCTURAL
+# DESC 'Samba Account'
+# MUST ( uid $ rid )
+# MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+# logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+# displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+# description $ userWorkstations $ primaryGroupID $ domain ))
+
+#objectclass ( 1.3.6.1.4.1.7165.2.2.3 NAME 'sambaAccount' SUP top AUXILIARY
+# DESC 'Samba Auxiliary Account'
+# MUST ( uid $ rid )
+# MAY ( cn $ lmPassword $ ntPassword $ pwdLastSet $ logonTime $
+# logoffTime $ kickoffTime $ pwdCanChange $ pwdMustChange $ acctFlags $
+# displayName $ smbHome $ homeDrive $ scriptPath $ profilePath $
+# description $ userWorkstations $ primaryGroupID $ domain ))
+
+########################################################################
+## END OF HISTORICAL ##
+########################################################################
+
+#######################################################################
+## Attributes used by Samba 3.0 schema ##
+#######################################################################
+
+##
+## Password hashes
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.24 NAME 'sambaLMPassword'
+ DESC 'LanManager Password'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.25 NAME 'sambaNTPassword'
+ DESC 'MD4 hash of the unicode password'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} SINGLE-VALUE )
+
+##
+## Account flags in string format ([UWDX ])
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.26 NAME 'sambaAcctFlags'
+ DESC 'Account Flags'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} SINGLE-VALUE )
+
+##
+## Password timestamps & policies
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.27 NAME 'sambaPwdLastSet'
+ DESC 'Timestamp of the last password update'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.28 NAME 'sambaPwdCanChange'
+ DESC 'Timestamp of when the user is allowed to update the password'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.29 NAME 'sambaPwdMustChange'
+ DESC 'Timestamp of when the password will expire'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.30 NAME 'sambaLogonTime'
+ DESC 'Timestamp of last logon'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.31 NAME 'sambaLogoffTime'
+ DESC 'Timestamp of last logoff'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.32 NAME 'sambaKickoffTime'
+ DESC 'Timestamp of when the user will be logged off automatically'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.48 NAME 'sambaBadPasswordCount'
+ DESC 'Bad password attempt count'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.49 NAME 'sambaBadPasswordTime'
+ DESC 'Time of the last bad password attempt'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.55 NAME 'sambaLogonHours'
+ DESC 'Logon Hours'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{42} SINGLE-VALUE )
+
+##
+## string settings
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.33 NAME 'sambaHomeDrive'
+ DESC 'Driver letter of home directory mapping'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{4} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.34 NAME 'sambaLogonScript'
+ DESC 'Logon script path'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.35 NAME 'sambaProfilePath'
+ DESC 'Roaming profile path'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.36 NAME 'sambaUserWorkstations'
+ DESC 'List of user workstations the user is allowed to logon to'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.37 NAME 'sambaHomePath'
+ DESC 'Home directory UNC path'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName'
+ DESC 'Windows NT domain to which the user belongs'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial'
+ DESC 'Base64 encoded user parameter string'
+ EQUALITY caseExactMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.54 NAME 'sambaPasswordHistory'
+ DESC 'Concatenated MD5 hashes of the salted NT passwords used on this account'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{32} )
+
+##
+## SID, of any type
+##
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.20 NAME 'sambaSID'
+ DESC 'Security ID'
+ EQUALITY caseIgnoreIA5Match
+ SUBSTR caseExactIA5SubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
+
+##
+## Primary group SID, compatible with ntSid
+##
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.23 NAME 'sambaPrimaryGroupSID'
+ DESC 'Primary Group Security ID'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.51 NAME 'sambaSIDList'
+ DESC 'Security ID List'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
+
+##
+## group mapping attributes
+##
+attributetype ( 1.3.6.1.4.1.7165.2.1.19 NAME 'sambaGroupType'
+ DESC 'NT Group Type'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+##
+## Store info on the domain
+##
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.21 NAME 'sambaNextUserRid'
+ DESC 'Next NT rid to give our for users'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.22 NAME 'sambaNextGroupRid'
+ DESC 'Next NT rid to give out for groups'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.39 NAME 'sambaNextRid'
+ DESC 'Next NT rid to give out for anything'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.40 NAME 'sambaAlgorithmicRidBase'
+ DESC 'Base at which the samba RID generation algorithm should operate'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.41 NAME 'sambaShareName'
+ DESC 'Share Name'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.42 NAME 'sambaOptionName'
+ DESC 'Option Name'
+ EQUALITY caseIgnoreMatch
+ SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.43 NAME 'sambaBoolOption'
+ DESC 'A boolean option'
+ EQUALITY booleanMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.44 NAME 'sambaIntegerOption'
+ DESC 'An integer option'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.45 NAME 'sambaStringOption'
+ DESC 'A string option'
+ EQUALITY caseExactIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption'
+ DESC 'A string list option'
+ EQUALITY caseIgnoreMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+##attributetype ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaPrivName'
+## SUP name )
+
+##attributetype ( 1.3.6.1.4.1.7165.2.1.52 NAME 'sambaPrivilegeList'
+## DESC 'Privileges List'
+## EQUALITY caseIgnoreIA5Match
+## SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
+
+attributetype ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags'
+ DESC 'Trust Password Flags'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+# "min password length"
+attributetype ( 1.3.6.1.4.1.7165.2.1.58 NAME 'sambaMinPwdLength'
+ DESC 'Minimal password length (default: 5)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "password history"
+attributetype ( 1.3.6.1.4.1.7165.2.1.59 NAME 'sambaPwdHistoryLength'
+ DESC 'Length of Password History Entries (default: 0 => off)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "user must logon to change password"
+attributetype ( 1.3.6.1.4.1.7165.2.1.60 NAME 'sambaLogonToChgPwd'
+ DESC 'Force Users to logon for password change (default: 0 => off, 2 => on)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "maximum password age"
+attributetype ( 1.3.6.1.4.1.7165.2.1.61 NAME 'sambaMaxPwdAge'
+ DESC 'Maximum password age, in seconds (default: -1 => never expire passwords)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "minimum password age"
+attributetype ( 1.3.6.1.4.1.7165.2.1.62 NAME 'sambaMinPwdAge'
+ DESC 'Minimum password age, in seconds (default: 0 => allow immediate password change)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "lockout duration"
+attributetype ( 1.3.6.1.4.1.7165.2.1.63 NAME 'sambaLockoutDuration'
+ DESC 'Lockout duration in minutes (default: 30, -1 => forever)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "reset count minutes"
+attributetype ( 1.3.6.1.4.1.7165.2.1.64 NAME 'sambaLockoutObservationWindow'
+ DESC 'Reset time after lockout in minutes (default: 30)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "bad lockout attempt"
+attributetype ( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold'
+ DESC 'Lockout users after bad logon attempts (default: 0 => off)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "disconnect time"
+attributetype ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff'
+ DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+# "refuse machine password change"
+attributetype ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange'
+ DESC 'Allow Machine Password changes (default: 0 => off)'
+ EQUALITY integerMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+
+
+
+
+#######################################################################
+## objectClasses used by Samba 3.0 schema ##
+#######################################################################
+
+## The X.500 data model (and therefore LDAPv3) says that each entry can
+## only have one structural objectclass. OpenLDAP 2.0 does not enforce
+## this currently but will in v2.1
+
+##
+## added new objectclass (and OID) for 3.0 to help us deal with backwards
+## compatibility with 2.2 installations (e.g. ldapsam_compat) --jerry
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY
+ DESC 'Samba 3.0 Auxilary SAM Account'
+ MUST ( uid $ sambaSID )
+ MAY ( cn $ sambaLMPassword $ sambaNTPassword $ sambaPwdLastSet $
+ sambaLogonTime $ sambaLogoffTime $ sambaKickoffTime $
+ sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $
+ displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $
+ sambaProfilePath $ description $ sambaUserWorkstations $
+ sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial $
+ sambaBadPasswordCount $ sambaBadPasswordTime $
+ sambaPasswordHistory $ sambaLogonHours))
+
+##
+## Group mapping info
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.4 NAME 'sambaGroupMapping' SUP top AUXILIARY
+ DESC 'Samba Group Mapping'
+ MUST ( gidNumber $ sambaSID $ sambaGroupType )
+ MAY ( displayName $ description $ sambaSIDList ))
+
+##
+## Trust password for trust relationships (any kind)
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.14 NAME 'sambaTrustPassword' SUP top STRUCTURAL
+ DESC 'Samba Trust Password'
+ MUST ( sambaDomainName $ sambaNTPassword $ sambaTrustFlags )
+ MAY ( sambaSID $ sambaPwdLastSet ))
+
+##
+## Whole-of-domain info
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL
+ DESC 'Samba Domain Information'
+ MUST ( sambaDomainName $
+ sambaSID )
+ MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $
+ sambaAlgorithmicRidBase $
+ sambaMinPwdLength $ sambaPwdHistoryLength $ sambaLogonToChgPwd $
+ sambaMaxPwdAge $ sambaMinPwdAge $
+ sambaLockoutDuration $ sambaLockoutObservationWindow $ sambaLockoutThreshold $
+ sambaForceLogoff $ sambaRefuseMachinePwdChange ))
+
+##
+## used for idmap_ldap module
+##
+objectclass ( 1.3.6.1.4.1.7165.2.2.7 NAME 'sambaUnixIdPool' SUP top AUXILIARY
+ DESC 'Pool for allocating UNIX uids/gids'
+ MUST ( uidNumber $ gidNumber ) )
+
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.8 NAME 'sambaIdmapEntry' SUP top AUXILIARY
+ DESC 'Mapping from a SID to an ID'
+ MUST ( sambaSID )
+ MAY ( uidNumber $ gidNumber ) )
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.9 NAME 'sambaSidEntry' SUP top STRUCTURAL
+ DESC 'Structural Class for a SID'
+ MUST ( sambaSID ) )
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.10 NAME 'sambaConfig' SUP top AUXILIARY
+ DESC 'Samba Configuration Section'
+ MAY ( description ) )
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.11 NAME 'sambaShare' SUP top STRUCTURAL
+ DESC 'Samba Share Section'
+ MUST ( sambaShareName )
+ MAY ( description ) )
+
+objectclass ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURAL
+ DESC 'Samba Configuration Option'
+ MUST ( sambaOptionName )
+ MAY ( sambaBoolOption $ sambaIntegerOption $ sambaStringOption $
+ sambaStringListoption $ description ) )
+
+
+## retired during privilege rewrite
+##objectclass ( 1.3.6.1.4.1.7165.2.2.13 NAME 'sambaPrivilege' SUP top AUXILIARY
+## DESC 'Samba Privilege'
+## MUST ( sambaSID )
+## MAY ( sambaPrivilegeList ) )
diff --git a/third_party/heimdal/tests/ldap/slapd-init.in b/third_party/heimdal/tests/ldap/slapd-init.in
new file mode 100644
index 0000000..f6e9fe9
--- /dev/null
+++ b/third_party/heimdal/tests/ldap/slapd-init.in
@@ -0,0 +1,58 @@
+#!/bin/sh
+# $Id$
+
+srcdir=@srcdir@
+
+rm -rf db schema
+mkdir db
+
+# kill of old slapd if running
+sh "${srcdir}/slapd-stop" > /dev/null
+
+SCHEMA_NEEDED="hdb core nis cosine inetorgperson openldap samba"
+
+SCHEMA_PATHS="${srcdir}/../../lib/hdb ${srcdir} /etc/ldap/schema /etc/openldap/schema /private/etc/openldap/schema /usr/share/openldap/schema"
+
+test -d schema || mkdir schema
+
+# setup needed schema files
+for f in $SCHEMA_NEEDED; do
+ if [ ! -r schema/$f.schema ]; then
+ for d in $SCHEMA_PATHS ; do
+ if [ -r $d/$f.schema ] ; then
+ cp $d/$f.schema schema/$f.schema
+ continue 2
+ fi
+ done
+ echo "SKIPPING TESTS: you need the following schema file: $f.schema"
+ exit 1
+ fi
+done
+
+touch modules.conf || exit 1
+
+if ! slapadd -d 0 -f "${srcdir}/slapd.conf" < "${srcdir}/init.ldif"; then
+ echo "moduleload back_bdb.la" >> modules.conf
+ if ! slapadd -d 0 -f "${srcdir}/slapd.conf" < "${srcdir}/init.ldif"; then
+ echo "modulepath /usr/lib/ldap" > modules.conf
+ echo "moduleload back_bdb.la" >> modules.conf
+ slapadd -d 0 -f "${srcdir}/slapd.conf" < "${srcdir}/init.ldif" || exit 1
+ fi
+fi
+
+cp "`which slapd`" . || true # fails if running
+
+echo "starting slapd"
+./slapd -d0 -f "${srcdir}/slapd.conf" -h ldapi://.%2Fldap-socket &
+slapd_pid=$!
+
+tries=0
+while kill -0 $slapd_pid && [ ! -S ldap-socket ] &&
+ ! ldapsearch -l 2 -w '' -D '' -b "o=TEST,dc=H5L,dc=SE" -s base -H ldapi://.%2Fldap-socket >/dev/null &&
+ [ $tries -lt 30 ]; do
+ sleep 1
+ tries=`expr 1 + $tries`
+done
+
+kill -0 $slapd_pid || exit 1
+[ -S ldap-socket ] || exit 1
diff --git a/third_party/heimdal/tests/ldap/slapd-stop b/third_party/heimdal/tests/ldap/slapd-stop
new file mode 100644
index 0000000..278d98a
--- /dev/null
+++ b/third_party/heimdal/tests/ldap/slapd-stop
@@ -0,0 +1,18 @@
+#!/bin/sh
+# $Id$
+
+echo stoping slapd
+
+# kill of old slapd
+if [ -f slapd.pid ]; then
+ kill `cat slapd.pid`
+ sleep 5
+fi
+if [ -f slapd.pid ]; then
+ kill -9 `cat slapd.pid`
+ rm -f slapd.pid
+ sleep 5
+fi
+
+exit 0
+
diff --git a/third_party/heimdal/tests/ldap/slapd.conf b/third_party/heimdal/tests/ldap/slapd.conf
new file mode 100644
index 0000000..caec472
--- /dev/null
+++ b/third_party/heimdal/tests/ldap/slapd.conf
@@ -0,0 +1,27 @@
+loglevel 0
+
+include schema/core.schema
+include schema/cosine.schema
+include schema/inetorgperson.schema
+include schema/openldap.schema
+include schema/nis.schema
+include schema/hdb.schema
+include schema/samba.schema
+
+
+pidfile slapd.pid
+argsfile slapd.args
+
+access to * by * write
+
+allow update_anon bind_anon_dn
+
+include modules.conf
+
+defaultsearchbase "o=TEST,dc=H5L,dc=SE"
+
+database bdb
+suffix "o=TEST,dc=H5L,dc=SE"
+directory db
+index objectClass eq
+index uid eq
diff --git a/third_party/heimdal/tests/plugin/Makefile.am b/third_party/heimdal/tests/plugin/Makefile.am
new file mode 100644
index 0000000..5dd43cc
--- /dev/null
+++ b/third_party/heimdal/tests/plugin/Makefile.am
@@ -0,0 +1,48 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+# for krb5_locl.h
+AM_CPPFLAGS += -I$(srcdir)/../../lib/krb5
+
+noinst_DATA = krb5.conf
+
+SCRIPT_TESTS = check-pac
+TESTS = $(SCRIPT_TESTS)
+
+port = 49188
+
+do_subst = sed -e 's,[@]srcdir[@],$(srcdir),g' \
+ -e 's,[@]env_setup[@],$(top_builddir)/tests/bin/setup-env,g' \
+ -e 's,[@]port[@],$(port),g' \
+ -e 's,[@]objdir[@],$(top_builddir)/tests/plugin,g' \
+ -e 's,[@]EGREP[@],$(EGREP),g'
+
+LDADD = ../../lib/krb5/libkrb5.la $(LIB_roken)
+
+check-pac: check-pac.in Makefile
+ $(do_subst) < $(srcdir)/check-pac.in > check-pac.tmp
+ chmod +x check-pac.tmp
+ mv check-pac.tmp check-pac
+
+krb5.conf: krb5.conf.in Makefile
+ $(do_subst) < $(srcdir)/krb5.conf.in > krb5.conf.tmp
+ mv krb5.conf.tmp krb5.conf
+
+lib_LTLIBRARIES = kdc_test_plugin.la
+
+kdc_test_plugin_la_SOURCES = kdc_test_plugin.c
+kdc_test_plugin_la_LDFLAGS = -module
+
+CLEANFILES= \
+ $(TESTS) \
+ server.keytab \
+ current-db* \
+ foopassword \
+ krb5.conf krb5.conf.tmp \
+ messages.log
+
+EXTRA_DIST = \
+ NTMakefile \
+ check-pac.in \
+ krb5.conf.in
diff --git a/third_party/heimdal/tests/plugin/NTMakefile b/third_party/heimdal/tests/plugin/NTMakefile
new file mode 100644
index 0000000..dc345c9
--- /dev/null
+++ b/third_party/heimdal/tests/plugin/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=tests\plugin
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/tests/plugin/check-pac.in b/third_party/heimdal/tests/plugin/check-pac.in
new file mode 100644
index 0000000..85bf8cd
--- /dev/null
+++ b/third_party/heimdal/tests/plugin/check-pac.in
@@ -0,0 +1,174 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
+# (Royal Institute of Technology, Stockholm, Sweden).
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the Institute nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+srcdir="@srcdir@"
+env_setup="@env_setup@"
+objdir="@objdir@"
+EGREP="@EGREP@"
+
+. ${env_setup}
+
+testfailed="echo test failed; cat messages.log; exit 1"
+
+# If there is no useful db support compiled in, disable test
+../db/have-db || exit 77
+
+R=TEST.H5L.SE
+R2=TEST2.H5L.SE
+
+port=@port@
+
+kadmin="${TESTS_ENVIRONMENT} ../../kadmin/kadmin -l -r ${R}"
+kdc="${TESTS_ENVIRONMENT} ../../kdc/kdc --addresses=localhost -P $port"
+
+server=host/datan.test.h5l.se
+cache="FILE:${objdir}/cache.krb5"
+keytabfile=${objdir}/server.keytab
+keytab="FILE:${keytabfile}"
+rodc_kvno="3058761729"
+
+kinit="${TESTS_ENVIRONMENT} ../../kuser/kinit -c $cache ${afs_no_afslog}"
+klist="${TESTS_ENVIRONMENT} ../../kuser/klist -c $cache"
+kgetcred="${TESTS_ENVIRONMENT} ../../kuser/kgetcred -c $cache"
+kdestroy="${TESTS_ENVIRONMENT} ../../kuser/kdestroy -c $cache ${afs_no_unlog}"
+test_apreq="${TESTS_ENVIRONMENT} ../../lib/krb5/test_ap-req"
+
+KRB5_CONFIG="${objdir}/krb5.conf"
+export KRB5_CONFIG
+
+rm -f ${keytabfile}
+rm -f current-db*
+rm -f out-*
+rm -f mkey.file*
+
+> messages.log
+
+echo Creating database
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${R} || exit 1
+${kadmin} add -p bar --use-defaults ${server}@${R} || exit 1
+${kadmin} modify --kvno=$rodc_kvno "krbtgt/${R}@${R}" || exit 1
+${kadmin} ext -k ${keytab} ${server}@${R} || exit 1
+
+${kadmin} \
+ init \
+ --realm-max-ticket-life=1day \
+ --realm-max-renewable-life=1month \
+ ${R2} || exit 1
+
+${kadmin} add -p foo --use-defaults foo@${R2} || exit 1
+${kadmin} add -p bar --use-defaults bar@${R2} || exit 1
+${kadmin} ext -k ${keytab} bar@${R2} || exit 1
+
+echo "Doing database check"
+${kadmin} check ${R} || exit 1
+${kadmin} check ${R2} || exit 1
+
+echo foo > ${objdir}/foopassword
+
+echo "Empty log"
+> messages.log
+
+echo Starting kdc
+${kdc} --detach --testing || { echo "kdc failed to start"; cat messages.log; exit 1; }
+kdcpid=`getpid kdc`
+
+trap "kill ${kdcpid}; echo signal killing kdc; exit 1;" EXIT
+
+ec=0
+
+echo "Check that KDC plugin module was loaded "
+grep "kdc plugin init" messages.log >/dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+
+echo "Getting client initial tickets"; > messages.log
+${kinit} --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting tickets" ; > messages.log
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Verify PAC on server"; > messages.log
+${test_apreq} --verify-pac ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client initial tickets (pac)"; > messages.log
+${kinit} --request-pac --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting tickets" ; > messages.log
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Verify PAC on server (pac)"; > messages.log
+${test_apreq} --verify-pac ${server}@${R} ${keytab} ${cache} || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client initial tickets (no pac)"; > messages.log
+${kinit} --no-request-pac --password-file=${objdir}/foopassword foo@${R} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting tickets" ; > messages.log
+${kgetcred} ${server}@${R} || { ec=1 ; eval "${testfailed}"; }
+echo "Verify PAC on server (no pac)"; > messages.log
+${test_apreq} --verify-pac ${server}@${R} ${keytab} ${cache} 2> /dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+${test_apreq} ${server}@${R} ${keytab} ${cache} 2> /dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Check the --no-verify-pac option"; > messages.log
+${test_apreq} --no-verify-pac ${server}@${R} ${keytab} ${cache} 2> /dev/null || \
+ { ec=1 ; eval "${testfailed}"; }
+${kdestroy}
+
+echo "Getting client initial tickets (no pac - realm config)"; > messages.log
+${kinit} --no-request-pac --password-file=${objdir}/foopassword foo@${R2} || \
+ { ec=1 ; eval "${testfailed}"; }
+echo "Getting tickets" ; > messages.log
+${kgetcred} bar@${R2} || { ec=1 ; eval "${testfailed}"; }
+echo "Verify PAC on server (no pac - realm config)"; > messages.log
+${test_apreq} --verify-pac bar@${R2} ${keytab} ${cache} 2> /dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+${test_apreq} bar@${R2} ${keytab} ${cache} 2> /dev/null && \
+ { ec=1 ; eval "${testfailed}"; }
+
+
+echo "killing kdc (${kdcpid})"
+kill $kdcpid || exit 1
+
+trap "" EXIT
+
+exit $ec
diff --git a/third_party/heimdal/tests/plugin/kdc_test_plugin.c b/third_party/heimdal/tests/plugin/kdc_test_plugin.c
new file mode 100644
index 0000000..45855d7
--- /dev/null
+++ b/third_party/heimdal/tests/plugin/kdc_test_plugin.c
@@ -0,0 +1,209 @@
+#include <string.h>
+#include <krb5_locl.h>
+#include <hdb.h>
+#include <hx509.h>
+#include <kdc.h>
+#include <kdc-plugin.h>
+
+static krb5_error_code KRB5_CALLCONV
+init(krb5_context context, void **ctx)
+{
+ krb5_warnx(context, "kdc plugin init");
+ *ctx = NULL;
+ return 0;
+}
+
+static void KRB5_CALLCONV
+fini(void *ctx)
+{
+}
+
+static krb5_error_code KRB5_CALLCONV
+pac_generate(void *ctx,
+ astgs_request_t r,
+ hdb_entry *client,
+ hdb_entry *server,
+ const krb5_keyblock *pk_replykey,
+ uint64_t pac_attributes,
+ krb5_pac *pac)
+{
+ krb5_context context = kdc_request_get_context((kdc_request_t)r);
+ krb5_error_code ret;
+ krb5_data data;
+
+ if ((pac_attributes & (KRB5_PAC_WAS_REQUESTED |
+ KRB5_PAC_WAS_GIVEN_IMPLICITLY)) == 0) {
+ *pac = NULL;
+ return 0;
+ }
+
+ krb5_warnx(context, "pac generate");
+
+ data.data = "\x00\x01";
+ data.length = 2;
+
+ ret = krb5_pac_init(context, pac);
+ if (ret)
+ return ret;
+
+ ret = krb5_pac_add_buffer(context, *pac, 1, &data);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static krb5_error_code KRB5_CALLCONV
+pac_verify(void *ctx,
+ astgs_request_t r,
+ krb5_const_principal new_ticket_client,
+ hdb_entry * delegation_proxy,
+ hdb_entry * client,
+ hdb_entry * server,
+ hdb_entry * krbtgt,
+ EncTicketPart *ticket,
+ krb5_pac pac)
+{
+ krb5_context context = kdc_request_get_context((kdc_request_t)r);
+ krb5_error_code ret;
+ krb5_data data;
+ krb5_cksumtype cstype;
+ uint16_t rodc_id;
+ krb5_enctype etype;
+ Key *key;
+
+ krb5_warnx(context, "pac_verify");
+
+ ret = krb5_pac_get_buffer(context, pac, 1, &data);
+ if (ret)
+ return ret;
+ krb5_data_free(&data);
+
+ ret = krb5_pac_get_kdc_checksum_info(context, pac, &cstype, &rodc_id);
+ if (ret)
+ return ret;
+
+ if (rodc_id == 0 || rodc_id != krbtgt->kvno >> 16) {
+ krb5_warnx(context, "Wrong RODCIdentifier");
+ return EINVAL;
+ }
+
+ ret = krb5_cksumtype_to_enctype(context, cstype, &etype);
+ if (ret)
+ return ret;
+
+ ret = hdb_enctype2key(context, krbtgt, NULL, etype, &key);
+ if (ret)
+ return ret;
+
+ return krb5_pac_verify(context, pac, 0, NULL, NULL, &key->key);
+}
+
+static void logit(const char *what, astgs_request_t r)
+{
+ krb5_context context = kdc_request_get_context((kdc_request_t)r);
+ const char *cname = kdc_request_get_cname((kdc_request_t)r);
+ const char *sname = kdc_request_get_sname((kdc_request_t)r);
+
+ krb5_warnx(context, "%s: client %s server %s",
+ what,
+ cname ? cname : "<unknown>",
+ sname ? sname : "<unknown>");
+}
+
+static krb5_error_code KRB5_CALLCONV
+client_access(void *ctx, astgs_request_t r)
+{
+ logit("client_access", r);
+
+ return 0;
+}
+
+static krb5_error_code KRB5_CALLCONV
+finalize_reply(void *ctx, astgs_request_t r)
+{
+ heim_number_t n;
+ krb5_error_code ret;
+
+ logit("finalize_reply", r);
+
+ n = heim_number_create(1234);
+ if (n == NULL)
+ return ENOMEM;
+
+ ret = kdc_request_set_attribute((kdc_request_t)r,
+ HSTR("org.h5l.tests.kdc-plugin"), n);
+ heim_release(n);
+
+ return ret;
+}
+
+static krb5_error_code KRB5_CALLCONV
+audit(void *ctx, astgs_request_t r)
+{
+ krb5_error_code ret = kdc_request_get_error_code((kdc_request_t)r);
+ heim_number_t n;
+
+ logit("audit", r);
+
+ if (ret)
+ return 0; /* finalize_reply only called in success */
+
+ n = kdc_request_get_attribute((kdc_request_t)r,
+ HSTR("org.h5l.tests.kdc-plugin"));
+
+ heim_assert(n && heim_number_get_int(n) == 1234,
+ "attribute not passed from finalize_reply");
+
+ if (n == NULL || heim_number_get_int(n) != 1234)
+ return EINVAL; /* return value is ignored, but for completeness */
+
+ return 0;
+}
+
+static krb5plugin_kdc_ftable kdc_plugin = {
+ KRB5_PLUGIN_KDC_VERSION_11,
+ init,
+ fini,
+ pac_generate,
+ pac_verify,
+ NULL, /* pac_update */
+ client_access,
+ NULL, /* referral_policy */
+ finalize_reply,
+ audit
+};
+
+static const krb5plugin_kdc_ftable *const kdc_plugins[] = {
+ &kdc_plugin
+};
+
+krb5_error_code KRB5_CALLCONV
+kdc_plugin_load(krb5_context context,
+ krb5_get_instance_func_t *get_instance,
+ size_t *num_plugins,
+ const krb5plugin_kdc_ftable *const **plugins);
+
+static uintptr_t KRB5_CALLCONV
+kdc_plugin_get_instance(const char *libname)
+{
+ if (strcmp(libname, "hdb") == 0)
+ return hdb_get_instance(libname);
+ else if (strcmp(libname, "krb5") == 0)
+ return krb5_get_instance(libname);
+
+ return 0;
+}
+
+krb5_error_code KRB5_CALLCONV
+kdc_plugin_load(krb5_context context,
+ krb5_get_instance_func_t *get_instance,
+ size_t *num_plugins,
+ const krb5plugin_kdc_ftable *const **plugins)
+{
+ *get_instance = kdc_plugin_get_instance;
+ *num_plugins = sizeof(kdc_plugins) / sizeof(kdc_plugins[0]);
+ *plugins = kdc_plugins;
+
+ return 0;
+}
diff --git a/third_party/heimdal/tests/plugin/krb5.conf.in b/third_party/heimdal/tests/plugin/krb5.conf.in
new file mode 100644
index 0000000..d188c31
--- /dev/null
+++ b/third_party/heimdal/tests/plugin/krb5.conf.in
@@ -0,0 +1,52 @@
+# $Id$
+
+[libdefaults]
+ default_realm = TEST.H5L.SE
+ no-addresses = TRUE
+
+ plugin_dir = @objdir@ @objdir@/.libs
+
+[appdefaults]
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+
+[realms]
+ TEST.H5L.SE = {
+ kdc = localhost:@port@
+ }
+ TEST2.H5L.SE = {
+ kdc = localhost:@port@
+ disable_pac = true
+ }
+
+[kdc]
+ enable-digest = true
+ allow-anonymous = true
+ digests_allowed = chap-md5,digest-md5,ntlm-v1,ntlm-v1-session,ntlm-v2,ms-chap-v2
+ strict-nametypes = true
+ synthetic_clients = true
+ enable_gss_preauth = true
+ gss_mechanisms_allowed = sanon-x25519
+ enable-pkinit = true
+ pkinit_identity = FILE:@srcdir@/../../lib/hx509/data/kdc.crt,@srcdir@/../../lib/hx509/data/kdc.key
+ pkinit_anchors = FILE:@srcdir@/../../lib/hx509/data/ca.crt
+ pkinit_pool = FILE:@srcdir@/../../lib/hx509/data/sub-ca.crt
+# pkinit_revoke = CRL:@srcdir@/../../lib/hx509/data/crl1.crl
+ pkinit_mappings_file = @srcdir@/pki-mapping
+ pkinit_allow_proxy_certificate = true
+
+ database = {
+ dbname = @objdir@/current-db
+ realm = TEST.H5L.SE
+ mkey_file = @objdir@/mkey.file
+ log_file = @objdir@/log.current-db.log
+ }
+
+[hdb]
+ db-dir = @objdir@
+
+[logging]
+ kdc = 0-/FILE:@objdir@/messages.log
+ default = 0-/FILE:@objdir@/messages.log
+
+[kadmin]
+# default_keys = arcfour-hmac-md5:pw-salt