From: Greg Hudson Date: Thu, 3 Sep 2015 16:46:39 +0000 (-0400) Subject: Add test cases for client referrals X-Git-Tag: krb5-1.14-alpha1~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1e4a0394d0085e48d732ab318f9cbe08e9359587;p=thirdparty%2Fkrb5.git 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. --- diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c index 5c61c23b10..a0e4970f0e 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@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 415802e1c0..559fbd5f7c 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@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@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM') +r1.kinit('abc@XYZ', 'pw', ['-E']) +r1.klist('abc\@XYZ@KRBTEST2.COM', 'krbtgt/KRBTEST2.COM') success('KDC host referral tests')