From: Greg Hudson Date: Fri, 11 Jan 2013 17:25:56 +0000 (-0500) Subject: Test KDC host-based referral support X-Git-Tag: krb5-1.12-alpha1~352 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b472ccc0a5856cb2757dd6af6a31896d0a25e00;p=thirdparty%2Fkrb5.git Test KDC host-based referral support Test the KDC host-based referral support in t_referral.py, using a new harness to call krb5_get_credentials with a specified server name type. Also use this new harness for the #7483 regression test, to avoid relying on an undocumented kvno extension. --- diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in index 354f12c569..da52894725 100644 --- a/src/tests/Makefile.in +++ b/src/tests/Makefile.in @@ -8,6 +8,8 @@ KRB5_RUN_ENV= @KRB5_RUN_ENV@ PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) +EXTRADEPSRCS= gcred.c hist.c kdbtest.c + TEST_DB = ./testdb TEST_REALM = FOO.TEST.REALM TEST_MKEY = footes @@ -18,6 +20,9 @@ TEST_PREFIX = "foo bar" KADMIN_OPTS= -d $(TEST_DB) -r $(TEST_REALM) -P $(TEST_MKEY) KTEST_OPTS= $(KADMIN_OPTS) -p $(TEST_PREFIX) -n $(TEST_NUM) -D $(TEST_DEPTH) +gcred: gcred.o $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o $@ gcred.o $(KRB5_BASE_LIBS) + hist: hist.o $(KDB5_DEPLIBS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o $@ hist.o $(KDB5_LIBS) $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) @@ -67,7 +72,7 @@ kdb_check: kdc.conf krb5.conf $(RUN_SETUP) $(VALGRIND) ../kadmin/dbutil/kdb5_util $(KADMIN_OPTS) destroy -f $(RM) $(TEST_DB)* stash_file -check-pytests:: hist kdbtest +check-pytests:: gcred hist kdbtest $(RUNPYTEST) $(srcdir)/t_general.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_iprop.py $(PYTESTFLAGS) $(RUNPYTEST) $(srcdir)/t_anonpkinit.py $(PYTESTFLAGS) diff --git a/src/tests/deps b/src/tests/deps index 2feac3c9d3..83bda31bd8 100644 --- a/src/tests/deps +++ b/src/tests/deps @@ -1 +1,43 @@ -# No dependencies here. +# +# Generated makefile dependencies follow. +# +$(OUTPRE)gcred.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ + $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ + $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ + $(top_srcdir)/include/krb5/clpreauth_plugin.h $(top_srcdir)/include/krb5/plugin.h \ + $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ + gcred.c +$(OUTPRE)hist.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/types.h \ + $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/krb5/krb5.h \ + $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ + $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ + $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ + $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ + $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ + $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ + $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/k5-buf.h \ + $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ + $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ + $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ + $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \ + $(top_srcdir)/include/kdb.h $(top_srcdir)/include/krb5.h \ + $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/clpreauth_plugin.h \ + $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ + $(top_srcdir)/include/socket-utils.h hist.c +$(OUTPRE)kdbtest.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \ + $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/kadm5/admin.h \ + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_err.h \ + $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/gssrpc/auth.h \ + $(top_srcdir)/include/gssrpc/auth_gss.h $(top_srcdir)/include/gssrpc/auth_unix.h \ + $(top_srcdir)/include/gssrpc/clnt.h $(top_srcdir)/include/gssrpc/rename.h \ + $(top_srcdir)/include/gssrpc/rpc.h $(top_srcdir)/include/gssrpc/rpc_msg.h \ + $(top_srcdir)/include/gssrpc/svc.h $(top_srcdir)/include/gssrpc/svc_auth.h \ + $(top_srcdir)/include/gssrpc/xdr.h $(top_srcdir)/include/kdb.h \ + $(top_srcdir)/include/krb5.h kdbtest.c diff --git a/src/tests/gcred.c b/src/tests/gcred.c new file mode 100644 index 0000000000..cb0ae6af5d --- /dev/null +++ b/src/tests/gcred.c @@ -0,0 +1,103 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* tests/gcred.c - Test harness for referrals */ +/* + * Copyright (C) 2012 by the Massachusetts Institute of Technology. + * 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. + */ + +/* + * This program is intended to be run from a python script as: + * + * gcred nametype princname + * + * where nametype is one of "unknown", "principal", "srv-inst", and "srv-hst", + * and princname is the name of the service principal. gcred acquires + * credentials for the specified server principal. On success, gcred displays + * the server principal name of the obtained credentials to stdout and exits + * with status 0. On failure, gcred displays the error message for the failed + * operation to stderr and exits with status 1. + */ + +#include "k5-int.h" + +static krb5_context ctx; + +static void +check(krb5_error_code code) +{ + const char *errmsg; + + if (code) { + errmsg = krb5_get_error_message(ctx, code); + fprintf(stderr, "%s\n", errmsg); + krb5_free_error_message(ctx, errmsg); + exit(1); + } +} + +int +main(int argc, char **argv) +{ + krb5_principal client, server; + krb5_ccache ccache; + krb5_creds in_creds, *creds; + char *name; + + check(krb5_init_context(&ctx)); + + /* Parse arguments. */ + assert(argc == 3); + check(krb5_parse_name(ctx, argv[2], &server)); + if (strcmp(argv[1], "unknown") == 0) + server->type = KRB5_NT_UNKNOWN; + else if (strcmp(argv[1], "principal") == 0) + server->type = KRB5_NT_PRINCIPAL; + else if (strcmp(argv[1], "srv-inst") == 0) + server->type = KRB5_NT_SRV_INST; + else if (strcmp(argv[1], "srv-hst") == 0) + server->type = KRB5_NT_SRV_HST; + else + abort(); + + check(krb5_cc_default(ctx, &ccache)); + check(krb5_cc_get_principal(ctx, ccache, &client)); + memset(&in_creds, 0, sizeof(in_creds)); + in_creds.client = client; + in_creds.server = server; + check(krb5_get_credentials(ctx, 0, ccache, &in_creds, &creds)); + check(krb5_unparse_name(ctx, creds->server, &name)); + printf("%s\n", name); + + krb5_free_unparsed_name(ctx, name); + krb5_free_creds(ctx, creds); + krb5_free_principal(ctx, client); + krb5_free_principal(ctx, server); + krb5_cc_close(ctx, ccache); + krb5_free_context(ctx); + return 0; +} diff --git a/src/tests/t_referral.py b/src/tests/t_referral.py index 985f9da70e..ff8527b7fa 100644 --- a/src/tests/t_referral.py +++ b/src/tests/t_referral.py @@ -1,16 +1,89 @@ #!/usr/bin/python from k5test import * -# We should have a comprehensive suite of KDC host referral tests -# here, based on the tests in the kdc_realm subdir. For now, we just -# have a regression test for #7483. - -# A KDC should not return a host referral to its own realm. -krb5_conf = {'domain_realm': {'y': 'KRBTEST.COM'}} -kdc_conf = {'realms': {'$realm': {'host_based_services': 'x'}}} -realm = K5Realm(krb5_conf=krb5_conf, kdc_conf=kdc_conf, create_host=False) +# Create a realm where the KDC has a [domain_realm] mapping for 'd' +# and clients will not try to use DNS to look up KDC addresses. The +# KDC believes it has a cross-realm TGT for REFREALM, but we won't +# actually create REFREALM. +nodns = {'libdefaults': {'dns_lookup_kdc': 'false'}} +drealm = {'domain_realm': {'d': 'REFREALM'}} +realm = K5Realm(krb5_conf=nodns, kdc_conf=drealm, create_host=False) +realm.addprinc('krbtgt/REFREALM') + +# Get credentials for a/x.d and check whether the KDC returned a referral. +def test(realm, nametype, expected_ref, msg): + out = realm.run(['./gcred', nametype, 'a/x.d'], expected_code=1) + if ((expected_ref and 'Cannot find KDC for realm "REFREALM"' not in out) or + (not expected_ref and 'not found in Kerberos database' not in out)): + fail(msg) + +# Create a modified KDC environment and restart the KDC. +def restart_kdc(realm, kdc_conf): + env = realm.special_env('extravars', True, kdc_conf=kdc_conf) + realm.stop_kdc() + realm.start_kdc(env=env) + +# With no KDC configuration besides [domain_realm], we should get a +# referral for a NT-SRV-HST or NT-SRV-INST server name, but not an +# NT-UNKNOWN or NT-PRINCIPAL server name. +test(realm, 'srv-hst', True, 'srv-hst, no variables') +test(realm, 'srv-inst', True, 'srv-inst, no variables') +test(realm, 'principal', False, 'principal, no variables') +test(realm, 'unknown', False, 'unknown, no variables') + +# With host_based_services matching the first server name component +# ("a"), we should get a referral for an NT-UNKNOWN server name. +# host_based_services can appear in either [kdcdefaults] or the realm +# section, with the realm value supplementing the kdcdefaults value. +# NT-SRV-HST server names should be unaffected by host_based_services, +# and NT-PRINCIPAL server names shouldn't get a referral regardless. +restart_kdc(realm, {'kdcdefaults': {'host_based_services': '*'}}) +test(realm, 'unknown', True, 'unknown, kdcdefaults hostbased *') +test(realm, 'principal', False, 'principal, kdcdefaults hostbased *') +restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'b,a,c'}}) +test(realm, 'unknown', True, 'unknown, kdcdefaults hostbased b,a,c') +restart_kdc(realm, {'realms': {'$realm': {'host_based_services': 'a b c'}}}) +test(realm, 'unknown', True, 'unknown, realm hostbased a b c') +restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'a'}, + 'realms': {'$realm': {'host_based_services': 'b c'}}}) +test(realm, 'unknown', True, 'unknown, kdcdefaults hostbased a (w/ realm)') +restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'b,c'}, + 'realms': {'$realm': {'host_based_services': 'a,b'}}}) +test(realm, 'unknown', True, 'unknown, realm hostbased a,b (w/ kdcdefaults)') +restart_kdc(realm, {'kdcdefaults': {'host_based_services': 'b,c'}}) +test(realm, 'unknown', False, 'unknown, kdcdefaults hostbased b,c') +test(realm, 'srv-hst', True, 'srv-hst, kdcdefaults hostbased b,c') + +# With no_host_referrals matching the first server name component, we +# should not get a referral even for NT-SRV-HOST server names +restart_kdc(realm, {'kdcdefaults': {'no_host_referral': '*'}}) +test(realm, 'srv-hst', False, 'srv-hst, kdcdefaults nohost *') +restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'b,a,c'}}) +test(realm, 'srv-hst', False, 'srv-hst, kdcdefaults nohost b,a,c') +restart_kdc(realm, {'realms': {'$realm': {'no_host_referral': 'a b c'}}}) +test(realm, 'srv-hst', False, 'srv-hst, realm nohost a b c') +restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'a'}, + 'realms': {'$realm': {'no_host_referral': 'b c'}}}) +test(realm, 'srv-hst', False, 'srv-hst, kdcdefaults nohost a (w/ realm)') +restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'b,c'}, + 'realms': {'$realm': {'no_host_referral': 'a,b'}}}) +test(realm, 'srv-hst', False, 'srv-hst, realm nohost a,b (w/ kdcdefaults)') +restart_kdc(realm, {'kdcdefaults': {'no_host_referral': 'b,c'}}) +test(realm, 'srv-hst', True, 'srv-hst, kdcdefaults nohost b,c') + +# no_host_referrals should override host_based_services for NT-UNKNWON +# server names. +restart_kdc(realm, {'kdcdefaults': {'no_host_referral': '*', + 'host_based_services': '*'}}) +test(realm, 'unknown', False, 'srv-hst, kdcdefaults nohost * hostbased *') + +# Regression test for #7483: a KDC should not return a host referral +# to its own realm. +drealm = {'domain_realm': {'d': 'KRBTEST.COM'}} +realm.stop() +realm = K5Realm(kdc_conf=drealm, create_host=False) tracefile = os.path.join(realm.testdir, 'trace') -realm.run(['env', 'KRB5_TRACE=' + tracefile, kvno, '-u', 'x/z.y@'], +realm.run(['env', 'KRB5_TRACE=' + tracefile, './gcred', 'srv-hst', 'a/x.d@'], expected_code=1) f = open(tracefile, 'r') trace = f.read()