]> eyrie.org Git - kerberos/kstart.git/commitdiff
Fix k5start -H and krenew -H with non-renewable tickets
authorRuss Allbery <rra@stanford.edu>
Thu, 5 Jan 2012 21:29:41 +0000 (13:29 -0800)
committerRuss Allbery <rra@stanford.edu>
Thu, 5 Jan 2012 21:29:41 +0000 (13:29 -0800)
Fix a regression introduced in kstart 4.0 that caused k5start -H and
krenew -H to fail and attempt reauthentication with non-renewable
tickets even if the lifetime was long enough.  Thanks to pod for the
report.

Makefile.am
NEWS
framework.c
tests/TESTS
tests/k5start/non-renewable-t [new file with mode: 0755]
tests/krenew/non-renewable-t [new file with mode: 0755]

index e0e5beffca4bd7df7c58af4f4d6a9037e477ede6..9a1b347f2e16a1e2ffe535e93c2b591c0c82b182 100644 (file)
@@ -12,10 +12,11 @@ EXTRA_DIST = .gitignore LICENSE autogen examples/krenew-agent k5start.pod   \
        tests/data/command tests/data/fake-aklog tests/docs/pod-spelling-t  \
        tests/docs/pod-t tests/k5start/afs-t tests/k5start/basic-t          \
        tests/k5start/daemon-t tests/k5start/errors-t tests/k5start/flags-t \
-       tests/k5start/keyring-t tests/k5start/perms-t                       \
-       tests/k5start/sigchld-t tests/kafs/basic-t tests/krenew/afs-t       \
-       tests/krenew/basic-t tests/krenew/daemon-t tests/krenew/errors-t    \
-       tests/krenew/keyring-t tests/libtest.pl tests/tap/libtap.sh         \
+       tests/k5start/keyring-t tests/k5start/non-renewable-t               \
+       tests/k5start/perms-t tests/k5start/sigchld-t tests/kafs/basic-t    \
+       tests/krenew/afs-t tests/krenew/basic-t tests/krenew/daemon-t       \
+       tests/krenew/errors-t tests/krenew/keyring-t                        \
+       tests/krenew/non-renewable-t tests/libtest.pl tests/tap/libtap.sh   \
        tests/util/xmalloc-t
 
 # The following library order matters for annoying reasons.  Older
diff --git a/NEWS b/NEWS
index f915da6d4f2ac205dbcc6b5a5478f63e91b69c56..1b1751ee107f2ee34de21f812e1899d62393c9cb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
                        User-Visible kstart Changes
 
+kstart 4.1 (unreleased)
+
+    Fix a regression introduced in kstart 4.0 that caused k5start -H and
+    krenew -H to fail and attempt reauthentication with non-renewable
+    tickets even if the lifetime was long enough.  Thanks to pod for the
+    report.
+
 kstart 4.0 (2011-12-29)
 
     Remove k4start from the distribution.  I no longer have a Kerberos v4
index 54692ca2e1212119013da811ade8473d7c19403d..9895c491ee4dd8f90db9f0cb12b0c72e66ec4408 100644 (file)
@@ -20,7 +20,7 @@
  * other is handled via callbacks.
  *
  * Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2006, 2007, 2008, 2009, 2010, 2011
+ * Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
  *     The Board of Trustees of the Leland Stanford Junior University
  *
  * See LICENSE for licensing terms.
@@ -158,11 +158,15 @@ ticket_expired(krb5_context ctx, struct config *config)
          * is arbitrary.  It just needs to be different than the error code
          * that indicates we can renew the ticket and coordinated with the
          * check in krenew's authentication callback.
+         *
+         * If the ticket is not going to expire, we skip this check.
+         * Otherwise, krenew -H 1 would fail even if the ticket had plenty of
+         * remaining lifespan if it was not renewable.
          */
-        then = outcreds->times.renew_till;
-        if (then < now + offset) {
-            code = KRB5KDC_ERR_KEY_EXP;
-            goto done;
+        if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) {
+            then = outcreds->times.renew_till;
+            if (then < now + offset)
+                code = KRB5KDC_ERR_KEY_EXP;
         }
     }
 
index 91e3cbafc57ea719d1856177af180b533d62a62d..af6328f10173d2f45b3014b174d4539a85e0e211 100644 (file)
@@ -6,6 +6,7 @@ k5start/daemon
 k5start/errors
 k5start/flags
 k5start/keyring
+k5start/non-renewable
 k5start/perms
 k5start/sigchld
 kafs/basic
@@ -15,6 +16,7 @@ krenew/basic
 krenew/daemon
 krenew/errors
 krenew/keyring
+krenew/non-renewable
 portable/asprintf
 portable/daemon
 portable/mkstemp
diff --git a/tests/k5start/non-renewable-t b/tests/k5start/non-renewable-t
new file mode 100755 (executable)
index 0000000..9f5a309
--- /dev/null
@@ -0,0 +1,77 @@
+#!/usr/bin/perl -w
+#
+# Ensure that non-renewable tickets don't cause spurious failure.
+#
+# k5start 4.0 had a bug where if tickets weren't renewable, k5start -H 1 would
+# attempt to reauthenticate.  Ensure that bug doesn't recur.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2012
+#     The Board of Trustees of the Leland Stanford Junior University
+#
+# See LICENSE for licensing terms.
+
+use Test::More;
+
+# The full path to the newly-built k5start client.
+our $K5START = "$ENV{BUILD}/../k5start";
+
+# The path to our data directory, which contains the keytab to use to test.
+our $DATA = "$ENV{BUILD}/data";
+
+# Load our test utility programs.
+require "$ENV{SOURCE}/libtest.pl";
+
+# We have to generate a local krb5.conf that disables any attempt to get
+# renewable tickets.  Try to locate the local krb5.conf that we're supposed to
+# use and skip if we can't find one.
+my $krb5conf = $ENV{KRB5_CONFIG};
+unless ($krb5conf) {
+    for my $path ('/etc', '/usr/local/etc', "$ENV{BUILD}/data") {
+        if (-r "$path/krb5.conf") {
+            $krb5conf = "$path/krb5.conf";
+            last;
+        }
+    }
+}
+if ($krb5conf) {
+    open (CONF, '<', $krb5conf) or BAIL_OUT ("cannot open $krb5conf: $!");
+    open (NEWCONF, '>', './krb5.conf')
+        or BAIL_OUT ("cannot create krb5.conf: $!");
+    while (<CONF>) {
+        next if /^\s*renew_lifetime\b/;
+        print NEWCONF $_;
+    }
+    close CONF;
+    close NEWCONF;
+    $ENV{KRB5_CONFIG} = './krb5.conf';
+} else {
+    plan skip_all => "no krb5.conf found, set KRB5_CONFIG";
+    exit 0;
+}
+
+# Decide whether we have the configuration to run the tests.
+my $principal;
+if (not -f "$DATA/test.keytab" or not -f "$DATA/test.principal") {
+    plan skip_all => "no keytab configuration";
+    exit 0;
+} else {
+    $principal = contents ("$DATA/test.principal");
+    $ENV{KRB5CCNAME} = 'krb5cc_test';
+    unlink 'krb5cc_test';
+    unless (kinit ("$DATA/test.keytab", $principal, '-l', '1h')) {
+        plan skip_all => 'cannot get non-renewable tickets';
+        exit 0;
+    }
+    plan tests => 3;
+}
+
+# Now, k5start should start without reauthenticating.
+my ($out, $err, $status)
+    = command ($K5START, '-H', '20', '-f', '/nonexistent', $principal);
+is ($status, 0, 'k5start -H 20 succeeds without reauthenticating');
+is ($err, '', ' with no errors');
+is ($out, '', ' and no output');
+
+# Clean up.
+unlink 'krb5cc_test', 'krb5.conf';
diff --git a/tests/krenew/non-renewable-t b/tests/krenew/non-renewable-t
new file mode 100755 (executable)
index 0000000..72d31c1
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/perl -w
+#
+# Ensure krenew -H works with non-renewable tickets.
+#
+# krenew normally requires tickets be renewable, but krenew -H should be happy
+# with a non-renewable ticket that nonetheless has sufficient renaming
+# lifespan.
+#
+# Written by Russ Allbery <rra@stanford.edu>
+# Copyright 2012
+#     The Board of Trustees of the Leland Stanford Junior University
+#
+# See LICENSE for licensing terms.
+
+use Test::More;
+
+# The full path to the newly-built krenew client.
+our $KRENEW = "$ENV{BUILD}/../krenew";
+
+# The path to our data directory, which contains the keytab to use to test.
+our $DATA = "$ENV{BUILD}/data";
+
+# Load our test utility programs.
+require "$ENV{SOURCE}/libtest.pl";
+
+# We have to generate a local krb5.conf that disables any attempt to get
+# renewable tickets.  Try to locate the local krb5.conf that we're supposed to
+# use and skip if we can't find one.
+my $krb5conf = $ENV{KRB5_CONFIG};
+unless ($krb5conf) {
+    for my $path ('/etc', '/usr/local/etc', "$ENV{BUILD}/data") {
+        if (-r "$path/krb5.conf") {
+            $krb5conf = "$path/krb5.conf";
+            last;
+        }
+    }
+}
+if ($krb5conf) {
+    open (CONF, '<', $krb5conf) or BAIL_OUT ("cannot open $krb5conf: $!");
+    open (NEWCONF, '>', './krb5.conf')
+        or BAIL_OUT ("cannot create krb5.conf: $!");
+    while (<CONF>) {
+        next if /^\s*renew_lifetime\b/;
+        print NEWCONF $_;
+    }
+    close CONF;
+    close NEWCONF;
+    $ENV{KRB5_CONFIG} = './krb5.conf';
+} else {
+    plan skip_all => "no krb5.conf found, set KRB5_CONFIG";
+    exit 0;
+}
+
+# Decide whether we have the configuration to run the tests.
+my $principal;
+if (not -f "$DATA/test.keytab" or not -f "$DATA/test.principal") {
+    plan skip_all => "no keytab configuration";
+    exit 0;
+} else {
+    $principal = contents ("$DATA/test.principal");
+    $ENV{KRB5CCNAME} = 'krb5cc_test';
+    unlink 'krb5cc_test';
+    unless (kinit ("$DATA/test.keytab", $principal, '-l', '1h')) {
+        plan skip_all => 'cannot get non-renewable tickets';
+        exit 0;
+    }
+    plan tests => 3;
+}
+
+# Now, krenew should run without reauthenticating even though the ticket isn't
+# renewable.
+my ($out, $err, $status) = command ($KRENEW, '-H', '20');
+is ($status, 0, 'krenew -H 20 succeeds without reauthenticating');
+is ($err, '', ' with no errors');
+is ($out, '', ' and no output');
+
+# Clean up.
+unlink 'krb5cc_test', 'krb5.conf';