diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
commit | 8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch) | |
tree | 4099e8021376c7d8c05bdf8503093d80e9c7bad0 /third_party/heimdal/tests/gss/check-context.in | |
parent | Initial commit. (diff) | |
download | samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip |
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/heimdal/tests/gss/check-context.in')
-rw-r--r-- | third_party/heimdal/tests/gss/check-context.in | 582 |
1 files changed, 582 insertions, 0 deletions
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 + |