krb5 commit: Add test cases for client referrals

Greg Hudson ghudson at mit.edu
Mon Sep 14 19:43:49 EDT 2015


https://github.com/krb5/krb5/commit/1e4a0394d0085e48d732ab318f9cbe08e9359587
commit 1e4a0394d0085e48d732ab318f9cbe08e9359587
Author: Greg Hudson <ghudson at mit.edu>
Date:   Thu Sep 3 12:46:39 2015 -0400

    Add test cases for client referrals
    
    Add support for out-of-realm referrals to the test KDB modlule, and
    add some tests to t_referral.py to exercise the KDC and client logic.

 src/plugins/kdb/test/kdb_test.c |   51 +++++++++++++++++++++++++++++++++-----
 src/tests/t_referral.py         |   21 ++++++++++++++++
 2 files changed, 65 insertions(+), 7 deletions(-)

diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c
index 5c61c23..a0e4970 100644
--- a/src/plugins/kdb/test/kdb_test.c
+++ b/src/plugins/kdb/test/kdb_test.c
@@ -39,6 +39,10 @@
  *         test = {
  *             alias = {
  *                 aliasname = canonname
+ *                 # For cross-realm aliases, only the realm part will
+ *                 # matter to the client.
+ *                 aliasname = @FOREIGN_REALM
+ *                 enterprise at PRINC = @FOREIGN_REALM
  *             }
  *             princs = {
  *                 krbtgt/KRBTEST.COM = {
@@ -296,9 +300,10 @@ test_get_principal(krb5_context context, krb5_const_principal search_for,
                    unsigned int flags, krb5_db_entry **entry)
 {
     krb5_error_code ret;
+    krb5_principal princ = NULL;
     krb5_principal_data empty_princ = { KV5M_PRINCIPAL };
     testhandle h = context->dal_handle->db_context;
-    char *search_name, *canon, *flagstr, **names, **key_strings;
+    char *search_name = NULL, *canon = NULL, *flagstr, **names, **key_strings;
     const char *ename;
     krb5_db_entry *ent;
 
@@ -308,20 +313,48 @@ test_get_principal(krb5_context context, krb5_const_principal search_for,
                                   KRB5_PRINCIPAL_UNPARSE_NO_REALM,
                                   &search_name));
     canon = get_string(h, "alias", search_name, NULL);
-    ename = (canon != NULL) ? canon : search_name;
+    if (canon != NULL) {
+        if (!(flags & KRB5_KDB_FLAG_ALIAS_OK)) {
+            ret = KRB5_KDB_NOENTRY;
+            goto cleanup;
+        }
+        check(krb5_parse_name(context, canon, &princ));
+        if (!krb5_realm_compare(context, search_for, princ)) {
+            if (flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) {
+                /* Return a client referral by creating an entry with only the
+                 * principal set. */
+                *entry = ealloc(sizeof(**entry));
+                (*entry)->princ = princ;
+                princ = NULL;
+                ret = 0;
+                goto cleanup;
+            } else {
+                /* We could look up a cross-realm TGS entry, but we don't need
+                 * that behavior yet. */
+                ret = KRB5_KDB_NOENTRY;
+                goto cleanup;
+            }
+        }
+        ename = canon;
+    } else {
+        check(krb5_copy_principal(context, search_for, &princ));
+        ename = search_name;
+    }
 
     /* Check that the entry exists. */
     set_names(h, "princs", ename, NULL);
     ret = profile_get_relation_names(h->profile, h->names, &names);
     if (ret == PROF_NO_RELATION) {
-        free(canon);
-        return KRB5_KDB_NOENTRY;
+        ret = KRB5_KDB_NOENTRY;
+        goto cleanup;
     }
     profile_free_list(names);
 
-    ent = ealloc(sizeof(*ent));
+    /* No error exits after this point. */
 
-    check(krb5_parse_name(context, ename, &ent->princ));
+    ent = ealloc(sizeof(*ent));
+    ent->princ = princ;
+    princ = NULL;
 
     flagstr = get_string(h, "princs", ename, "flags");
     if (flagstr != NULL) {
@@ -350,8 +383,12 @@ test_get_principal(krb5_context context, krb5_const_principal search_for,
     check(krb5_dbe_update_mod_princ_data(context, ent, 0, &empty_princ));
 
     *entry = ent;
+
+cleanup:
+    krb5_free_unparsed_name(context, search_name);
+    krb5_free_principal(context, princ);
     free(canon);
-    return 0;
+    return ret;
 }
 
 static void
diff --git a/src/tests/t_referral.py b/src/tests/t_referral.py
index 415802e..559fbd5 100755
--- a/src/tests/t_referral.py
+++ b/src/tests/t_referral.py
@@ -102,5 +102,26 @@ trace = f.read()
 f.close()
 if 'back to same realm' in trace:
     fail('KDC returned referral to service realm')
+realm.stop()
+
+# Test client referrals.  Use the test KDB module for KRBTEST1.COM to
+# simulate referrals since our built-in modules do not support them.
+# No cross-realm TGTs are necessary.
+kdcconf = {'realms': {'$realm': {'database_module': 'test'}},
+           'dbmodules': {'test': {'db_library': 'test',
+                                  'alias': {'user': '@KRBTEST2.COM',
+                                            'abc at XYZ': '@KRBTEST2.COM'}}}}
+r1, r2 = cross_realms(2, xtgts=(),
+                      args=({'kdc_conf': kdcconf, 'create_kdb': False}, None),
+                      create_host=False)
+r2.addprinc('abc\@XYZ', 'pw')
+r1.start_kdc()
+out = r1.kinit('user', expected_code=1)
+if 'not found in Kerberos database' not in out:
+    fail('Expected error not seen for referral without canonicalize flag')
+r1.kinit('user', password('user'), ['-C'])
+r1.klist('user at KRBTEST2.COM', 'krbtgt/KRBTEST2.COM')
+r1.kinit('abc at XYZ', 'pw', ['-E'])
+r1.klist('abc\@XYZ at KRBTEST2.COM', 'krbtgt/KRBTEST2.COM')
 
 success('KDC host referral tests')


More information about the cvs-krb5 mailing list