KDC realm referral test
authorTom Yu <tlyu@mit.edu>
Mon, 13 Apr 2009 20:26:27 +0000 (20:26 +0000)
committerTom Yu <tlyu@mit.edu>
Mon, 13 Apr 2009 20:26:27 +0000 (20:26 +0000)
pull up r22040 from trunk

 KDC realm referral test

ticket: 6457
version_fixed: 1.7
tags: pullup

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-7@22204 dc483132-0cff-0310-8789-dd5450dbe970

17 files changed:
src/tests/kdc_realm/input_conf/kdc_pri_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/kdc_ref_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priCL_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priKDC_1_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priKDC_2_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priKDC_3_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priKDC_4_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priKDC_5_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priKDC_6_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priKDC_7_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priKDC_8_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_priKDC_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/krb5_ref_template.conf [new file with mode: 0755]
src/tests/kdc_realm/input_conf/test_KDCs.conf [new file with mode: 0644]
src/tests/kdc_realm/input_conf/test_princs.conf [new file with mode: 0644]
src/tests/kdc_realm/input_conf/test_setup.conf [new file with mode: 0644]
src/tests/kdc_realm/kdcref.py [new file with mode: 0755]

diff --git a/src/tests/kdc_realm/input_conf/kdc_pri_template.conf b/src/tests/kdc_realm/input_conf/kdc_pri_template.conf
new file mode 100755 (executable)
index 0000000..31b2f92
--- /dev/null
@@ -0,0 +1,13 @@
+[kdcdefaults]
+       kdc_ports = 7777
+
+[realms]
+       Y.COM = {
+               database_name = %(tier2)s/principal
+               admin_keytab = FILE:%(tier2)s/kadm5.keytab
+               acl_file = %(tier2)s/kadm5.acl
+               key_stash_file = %(tier2)s/.k5.ATHENA.MIT.EDU
+               kdc_ports = 7777
+               max_life = 10h 0m 0s
+               max_renewable_life = 7d 0h 0m 0s
+       }
diff --git a/src/tests/kdc_realm/input_conf/kdc_ref_template.conf b/src/tests/kdc_realm/input_conf/kdc_ref_template.conf
new file mode 100755 (executable)
index 0000000..819713c
--- /dev/null
@@ -0,0 +1,13 @@
+[kdcdefaults]
+       kdc_ports = 7778
+
+[realms]
+       Z.COM = {
+               database_name = %(tier1)s/principal
+               admin_keytab = FILE:%(tier1)s/kadm5.keytab
+               acl_file = %(tier1)s/kadm5.acl
+               key_stash_file = %(tier1)s/.k5.ATHENA.MIT.EDU
+               kdc_ports = 7778
+               max_life = 10h 0m 0s
+               max_renewable_life = 7d 0h 0m 0s
+       }
diff --git a/src/tests/kdc_realm/input_conf/krb5_priCL_template.conf b/src/tests/kdc_realm/input_conf/krb5_priCL_template.conf
new file mode 100755 (executable)
index 0000000..7e31eed
--- /dev/null
@@ -0,0 +1,34 @@
+[libdefaults]
+       default_realm = Y.COM
+    default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+[realms]
+       Y.COM = {
+               admin_server = KERBEROS.Y.COM
+        kdc = %(localFQDN)s:7777
+               default_domain = Y.COM
+       }
+       Z.COM = {
+               admin_server = KERBEROS.Z.COM
+               kdc = %(localFQDN)s:7778
+               default_domain = Z.COM
+       }
+
+[domain_realm]
+#      .mit.edu = Y.COM
+       %(localFQDN)s = Y.COM
+       .%(localFQDN)s = Y.COM
+    .y.com = Y.COM 
+       y.com = Y.COM
+       
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc_cl.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_priKDC_1_template.conf b/src/tests/kdc_realm/input_conf/krb5_priKDC_1_template.conf
new file mode 100755 (executable)
index 0000000..7a197ca
--- /dev/null
@@ -0,0 +1,30 @@
+[libdefaults]
+       default_realm = Y.COM
+       default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+
+[kdcdefaults]
+       no_host_referral = * 
+       host_based_services = *
+
+[realms]
+       Y.COM = {
+               kdc = %(localFQDN)s:7777
+       }
+
+[domain_realm]
+       mybox.mit.edu=Z.COM
+       %(localFQDN)s=Y.COM
+       .y.com = Y.COM 
+       y.com = Y.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_priKDC_2_template.conf b/src/tests/kdc_realm/input_conf/krb5_priKDC_2_template.conf
new file mode 100755 (executable)
index 0000000..6f6994f
--- /dev/null
@@ -0,0 +1,31 @@
+[libdefaults]
+       default_realm = Y.COM
+       default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+
+[kdcdefaults]
+       no_host_referral = host1  
+       
+
+[realms]
+       Y.COM = {
+               kdc = %(localFQDN)s:7777
+               host_based_services = *
+       }
+
+[domain_realm]
+       mybox.mit.edu=Z.COM
+       %(localFQDN)s=Y.COM
+       .y.com = Y.COM 
+       y.com = Y.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_priKDC_3_template.conf b/src/tests/kdc_realm/input_conf/krb5_priKDC_3_template.conf
new file mode 100755 (executable)
index 0000000..d04ab8c
--- /dev/null
@@ -0,0 +1,30 @@
+[libdefaults]
+       default_realm = Y.COM
+    default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+
+[kdcdefaults]
+#      no_host_referral = * 
+#      host_based_services = *
+
+[realms]
+       Y.COM = {
+               kdc = %(localFQDN)s:7777
+       }
+
+[domain_realm]
+       mybox.mit.edu = Z.COM
+       %(localFQDN)s = Y.COM
+       .y.com = Y.COM 
+       y.com = Y.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_priKDC_4_template.conf b/src/tests/kdc_realm/input_conf/krb5_priKDC_4_template.conf
new file mode 100755 (executable)
index 0000000..751b22a
--- /dev/null
@@ -0,0 +1,30 @@
+[libdefaults]
+       default_realm = Y.COM
+    default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+
+[kdcdefaults]
+       host_based_services = *
+
+[realms]
+       Y.COM = {
+               kdc = %(localFQDN)s:7777
+               no_host_referral = host1, * host2               
+       }
+
+[domain_realm]
+       mybox.mit.edu = Z.COM
+       %(localFQDN)s = Y.COM
+       .y.com = Y.COM 
+       y.com = Y.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_priKDC_5_template.conf b/src/tests/kdc_realm/input_conf/krb5_priKDC_5_template.conf
new file mode 100755 (executable)
index 0000000..6d1d2fa
--- /dev/null
@@ -0,0 +1,30 @@
+[libdefaults]
+       default_realm = Y.COM
+    default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+
+[kdcdefaults]
+       no_host_referral = host1 testHost host2 
+       host_based_services = *
+
+[realms]
+       Y.COM = {
+               kdc = %(localFQDN)s:7777
+       }
+
+[domain_realm]
+       mybox.mit.edu = Z.COM
+       %(localFQDN)s = Y.COM
+       .y.com = Y.COM 
+       y.com = Y.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_priKDC_6_template.conf b/src/tests/kdc_realm/input_conf/krb5_priKDC_6_template.conf
new file mode 100755 (executable)
index 0000000..b67bbbb
--- /dev/null
@@ -0,0 +1,31 @@
+[libdefaults]
+       default_realm = Y.COM
+    default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+
+[kdcdefaults]
+#      no_host_referral = * 
+       host_based_services = *
+
+[realms]
+       Y.COM = {
+               kdc = %(localFQDN)s:7777
+               no_host_referral =  testHost
+       }
+
+[domain_realm]
+       mybox.mit.edu = Z.COM
+       %(localFQDN)s = Y.COM
+       .y.com = Y.COM 
+       y.com = Y.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_priKDC_7_template.conf b/src/tests/kdc_realm/input_conf/krb5_priKDC_7_template.conf
new file mode 100755 (executable)
index 0000000..ed0ddc7
--- /dev/null
@@ -0,0 +1,29 @@
+[libdefaults]
+       default_realm = Y.COM
+    default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+
+[kdcdefaults]
+       host_based_services = testHost
+
+[realms]
+       Y.COM = {
+               kdc = %(localFQDN)s:7777
+       }
+
+[domain_realm]
+       mybox.mit.edu = Z.COM
+       %(localFQDN)s = Y.COM
+       .y.com = Y.COM 
+       y.com = Y.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_priKDC_8_template.conf b/src/tests/kdc_realm/input_conf/krb5_priKDC_8_template.conf
new file mode 100755 (executable)
index 0000000..fa01e38
--- /dev/null
@@ -0,0 +1,33 @@
+[libdefaults]
+       default_realm = Y.COM
+    default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+
+[kdcdefaults]
+       host_based_services = host1
+
+
+[realms]
+       Y.COM = {
+               kdc = %(localFQDN)s:7777
+               host_based_services = host2
+#              host_based_services = testHost 
+               host_based_services = host3
+       }
+
+[domain_realm]
+       mybox.mit.edu = Z.COM
+       %(localFQDN)s = Y.COM
+       .y.com = Y.COM 
+       y.com = Y.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_priKDC_template.conf b/src/tests/kdc_realm/input_conf/krb5_priKDC_template.conf
new file mode 100755 (executable)
index 0000000..4066de3
--- /dev/null
@@ -0,0 +1,30 @@
+[libdefaults]
+       default_realm = Y.COM
+    default_keytab_name = FILE:%(tier2)s/krb5.keytab
+       default_tkt_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       default_tgs_enctypes = aes256-cts-hmac-sha1-96  des3-hmac-sha1 des-cbc-crc 
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+
+[kdcdefaults]
+#      no_host_referral = * 
+       host_based_services = *
+
+[realms]
+       Y.COM = {
+               kdc = %(localFQDN)s:7777
+       }
+
+[domain_realm]
+       mybox.mit.edu = Z.COM
+       %(localFQDN)s = Y.COM
+       .y.com = Y.COM 
+       y.com = Y.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier2)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/krb5_ref_template.conf b/src/tests/kdc_realm/input_conf/krb5_ref_template.conf
new file mode 100755 (executable)
index 0000000..ccfc2d7
--- /dev/null
@@ -0,0 +1,27 @@
+[libdefaults]
+       default_realm = Z.COM
+    default_keytab_name = FILE:%(tier1)s/krb5.keytab
+       default_tkt_enctypes =  aes128-cts-hmac-sha1-96 des3-hmac-sha1 des-cbc-crc aes256-cts-hmac-sha1-96 aes128-cts
+       default_tgs_enctypes =  aes128-cts-hmac-sha1-96 des3-hmac-sha1 des-cbc-crc aes256-cts-hmac-sha1-96 aes128-cts
+       dns_lookup_kdc = true
+       dns_lookup_realm = false
+
+[realms]
+       Z.COM = {
+               admin_server = KERBEROS.Z.COM           
+           kdc = %(localFQDN)s:7778
+               default_domain = Z.COM
+       }
+
+[domain_realm]
+       %(localFQDN)s=Z.COM
+       .%(localFQDN)s=Z.COM
+       .z.com = Z.COM 
+       z.com = Z.COM 
+
+[dbmodules]
+       db_module_dir = %(srcdir)s/plugins/kdb/db2
+
+[logging]
+       kdc = FILE:%(tier1)s/krb5kdc.log
+
diff --git a/src/tests/kdc_realm/input_conf/test_KDCs.conf b/src/tests/kdc_realm/input_conf/test_KDCs.conf
new file mode 100644 (file)
index 0000000..cfb6f87
--- /dev/null
@@ -0,0 +1,9 @@
+krb5_priKDC_template.conf,0
+krb5_priKDC_1_template.conf,1
+krb5_priKDC_2_template.conf,0
+krb5_priKDC_3_template.conf,0
+krb5_priKDC_4_template.conf,1
+krb5_priKDC_5_template.conf,1
+krb5_priKDC_6_template.conf,1
+krb5_priKDC_7_template.conf,0
+krb5_priKDC_8_template.conf,0
\ No newline at end of file
diff --git a/src/tests/kdc_realm/input_conf/test_princs.conf b/src/tests/kdc_realm/input_conf/test_princs.conf
new file mode 100644 (file)
index 0000000..fb2c9fc
--- /dev/null
@@ -0,0 +1 @@
+princUser/admin
\ No newline at end of file
diff --git a/src/tests/kdc_realm/input_conf/test_setup.conf b/src/tests/kdc_realm/input_conf/test_setup.conf
new file mode 100644 (file)
index 0000000..7d36973
--- /dev/null
@@ -0,0 +1,5 @@
+sandboxDir=tests/kdc_realm/sandbox
+testKDCconf=test_KDCs.conf
+principals=test_princs.conf
+tier1=sandbox/tier1
+tier2=sandbox/tier2
\ No newline at end of file
diff --git a/src/tests/kdc_realm/kdcref.py b/src/tests/kdc_realm/kdcref.py
new file mode 100755 (executable)
index 0000000..6c1f2ab
--- /dev/null
@@ -0,0 +1,325 @@
+import os
+import sys
+import time
+from subprocess import Popen, PIPE, STDOUT
+import signal
+import socket
+import errno
+import shutil
+
+
+class LaunchError(Exception):
+    """ Exception class to signal startup error"""
+    pass
+
+class AdminError(Exception):
+    """ Exception class to handle admin errors"""
+    pass
+
+
+class Launcher:
+    
+    def __init__(self, path):
+        self._buildDir = path
+        self._confDir = '%s/tests/kdc_realm/input_conf' %  self._buildDir    
+        confFile ='%s/test_setup.conf' % self._confDir       
+        confParams = self._testSetup(confFile)       
+        self._sandboxDir = '%s/%s' % (self._buildDir,confParams['sandboxDir'])
+        self._sandboxTier1 = '%s/%s' % (self._sandboxDir, 'tier1')
+        self._sandboxTier2 = '%s/%s' % (self._sandboxDir, 'tier2')
+        self._configurations = self._readServerConfiguration('%s/%s' % (self._confDir,confParams['testKDCconf']))
+        self._principals = self._readTestInputs('%s/%s' % (self._confDir,confParams['principals']))
+        os.environ["LD_LIBRARY_PATH"] = '%s/lib' % self._buildDir
+        self._pidRefKDC = 0
+        self._pidMap = dict()
+        self._initialized = False
+        self._tier1Init = False
+        self._tier2Init = False
+        self._vars = {'srcdir': self._buildDir, 
+                      'tier1':self._sandboxTier1, 
+                      'tier2':self._sandboxTier2, 
+                      'localFQDN':socket.getfqdn()}
+    def _launchKDC(self, tierId, args, env):
+        """
+        Launching KDC server
+        """
+        cmd = '%s/kdc/krb5kdc' % self._buildDir
+        handle = Popen([cmd, args], env=env)    
+        time.sleep(1)
+        # make sure that process is running
+        rc = handle.poll()
+        if rc is None:
+            print 'KDC server has been launched: pid=%s, tier=%s' % (handle.pid, tierId)
+            self._pidMap[handle.pid] = 1            
+            return handle.pid
+        else:
+            raise LaunchError, 'Failed to launch kdc server'
+
+
+    def _prepSandbox(self):
+         for tierId in range(1,3):
+            tierdir = '%s/tier%i' % (self._sandboxDir, tierId)
+            if  os.path.exists(tierdir):
+                shutil.rmtree(tierdir)                           
+            os.makedirs(tierdir, 0777)
+                
+
+    def _kill(self, pid = None):
+        """
+         Kill specific process or group saved in pidMap 
+        """
+        if pid is None:
+            target = self._pidMap.keys()
+        else:
+            target = [pid]
+        for p in target:
+            if p in self._pidMap:
+                del self._pidMap[p]
+            try:
+                os.kill(p, signal.SIGKILL)
+            except OSError:
+                pass
+        
+        
+    def _createDB(self, env):
+        """
+        Creating DB
+        """
+        cmd = '%s/kadmin/dbutil/kdb5_util'  % self._buildDir                
+        p = Popen([cmd, 'create', '-s'], env = env, stdin=PIPE, stdout=PIPE, stderr=PIPE)        
+        (out, err) = p.communicate('a\na\n')
+        if p.returncode != 0:
+            err_msg = 'Failed to create DB: %s' % err
+            raise LaunchError, err_msg
+
+        
+    def _launchClient(self, args, env):
+        """
+        kinit & kvno
+        """
+        self._addPrinc(args, env)
+        p = Popen(['kinit', args], env = env, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+        (out, err) = p.communicate('a\n')
+        if int(p.wait()) == 0:
+            self._initialized = True            
+        else:
+            err_msg = 'Failed to kinit client: %s' % err
+            raise AdminError, err_msg      
+
+        # testHost', 'mybox.mit.edu is a srv defined in referral KDC. Get its kvno 
+        cmd = '%s/clients/kvno/kvno' % self._buildDir 
+        handle = Popen([cmd, '-C', '-S', 'testHost', 'mybox.mit.edu'], 
+                       env = env, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+        (out, err) = handle.communicate()
+        handle.wait()
+        print 'kvno return code: %s' % handle.returncode
+
+        # Cleanup cached info
+        p = Popen(['kdestroy'], env = env, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+        (out, err) = p.communicate()
+        if int(p.wait()) != 0:
+            err_msg = 'Failed to kdestroy cashed tickets: %s' % err
+            raise AdminError, err_msg
+        
+        return handle.returncode
+    
+            
+    def _addPrinc(self, args, env):
+        """
+        Add Principal
+        """     
+        msg = 'addprinc -pw a %s' % args
+        p = Popen(['kadmin.local' ], env = env, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+        (out, err) = p.communicate(msg)
+        if int(p.wait()) != 0:
+            err_msg = 'Failed to add principal %s' % err_msg 
+            raise AdminError, err_msg
+
+        
+    def _crossRealm(self, r_local, r_remote, env):
+        """
+        Croos-realm setup
+        """     
+        msg = 'addprinc  -pw a krbtgt/%s@%s' % (r_remote, r_local)
+        p = Popen(['kadmin.local' ], env = env, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+        (out, err) = p.communicate(msg)
+        if int(p.wait()) != 0:
+            err_msg = 'Failed to set cross-realm: %s' % err
+            raise AdminError, err_msg 
+        
+        msg = 'addprinc  -pw a krbtgt/%s@%s' % (r_local, r_remote)
+        p = Popen(['kadmin.local' ], env = env, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+        (out, err) = p.communicate(msg)
+        if int(p.wait()) != 0:
+            err_msg = 'Failed to set cross-realm: %s' % err
+            raise AdminError, err_msg 
+
+        
+    def _launchRefKDC(self,test_env):
+        """
+        Launch referral KDC 
+        """
+        test_env["KRB5_CONFIG"] = '%s/krb5.conf' % self._sandboxTier1
+        test_env["KRB5_KDC_PROFILE"] = '%s/kdc.conf' % self._sandboxTier1      
+        server_args = '-n'
+        if self._tier1Init == False:
+            # Create adequate to the environment config files         
+            self._createFileFromTemplate('%s' % test_env["KRB5_CONFIG"],
+                        '%s/%s' % (self._confDir,'krb5_ref_template.conf'), 
+                        self._vars)
+            self._createFileFromTemplate('%s' % test_env["KRB5_KDC_PROFILE"],
+                        '%s/%s' % (self._confDir, 'kdc_ref_template.conf'), 
+                        self._vars)
+            
+            # create DB for  KDC to be referred to
+            pid = self._createDB(test_env)
+            
+            # launch KDC to be referred to
+            self._pidRefKDC = self._launchKDC(1, server_args, test_env)
+            # The tests run against 'testHost/mybox.mit.edu' srv. 
+            args = 'testHost/mybox.mit.edu'
+            self._addPrinc(args, test_env)
+            self._crossRealm('Z.COM', 'Y.COM', test_env)
+            self._tier1Init = True
+        
+        
+    def _launchTestingPair(self, srvParam,clntParam):
+        # launch KDC       
+        server_env = os.environ.copy()
+        server_env["KRB5_KDC_PROFILE"] = '%s/kdc.conf' % self._sandboxTier2  
+        server_env["KRB5_CONFIG"] = '%s/krb5_KDC.conf' % self._sandboxTier2       
+        server_args = '-n'
+        self._createFileFromTemplate('%s' % server_env["KRB5_CONFIG"],
+                                     '%s/%s' % (self._confDir,srvParam),
+                                     self._vars)
+        self._createFileFromTemplate('%s' % server_env["KRB5_KDC_PROFILE"],
+                                     '%s/%s' % (self._confDir,'kdc_pri_template.conf'),
+                                     self._vars)
+        if self._tier2Init == False:
+            pid = self._createDB(server_env)
+            self._crossRealm('Y.COM', 'Z.COM', server_env)            
+            self._tier2Init = True
+            
+        server = self._launchKDC( 2, server_args, server_env)
+        
+       # launch client
+        client_env = os.environ.copy()
+        client_env["KRB5_CONFIG"] = '%s/krb5_CL.conf' % self._sandboxTier2    
+        self._createFileFromTemplate('%s' % client_env["KRB5_CONFIG"],
+                        '%s/%s' % (self._confDir, 'krb5_priCL_template.conf'),
+                         self._vars)  
+        client_env["KRB5_KDC_PROFILE"] = server_env["KRB5_KDC_PROFILE"]                    
+        rc = self._launchClient(clntParam, client_env)
+        self._kill(server)
+        return rc
+            
+    def run(self, args):
+        """
+        run the test
+        """
+        test_env = os.environ.copy()
+        test_env["SRCDIR"] = '%s' % self._buildDir
+        
+        # create sandbox file directory if it does not exist
+        self._prepSandbox()
+
+        if self._tier1Init == False:
+            self._launchRefKDC(test_env)
+       
+        result = dict()
+        for princs in self._principals:
+            for conf in self._configurations:                                         
+                rc = self._launchTestingPair( conf['confName'], princs % self._vars)
+                result[conf['confName']] = {'expected':conf['expected'], 'actual':rc}
+                print 'Test code for configuration %s principal %s: %s' % (conf, princs, rc)        
+        return result
+
+
+    def _readTestInputs(self, path):
+        f = open(path, 'r')
+        result = []
+        for line in f:
+            result.append(line.rstrip())
+        f.close()
+        return result
+
+    def _readServerConfiguration(self, path):
+        f = open(path, 'r')
+        result = []
+        for line in f:
+            fields = (line.rstrip()).split(',')
+            result.append({'confName':fields[0],'expected':fields[1]})
+        f.close()
+        return result
+
+    def _testSetup(self, path):
+        print path
+        f = open(path, 'r')
+        result = dict()
+        for line in f:
+            try:
+                (a,v) = line.rstrip().split('=')
+                result[a]=v
+            except:
+                print 'bad format for config file, line: %s' % line
+                return None
+        f.close()
+        return result
+
+    
+    def _createFileFromTemplate(self, outpath, template, vars):
+        fin = open(template, 'r')
+        result = fin.read() % vars
+        fin.close()
+        fout = open(outpath, 'w')
+        fout.write(result)
+        fout.close()
+
+        
+    def _getDNS(self):
+        print socket.getfqdn()
+        
+        
+    def printTestResults(self, testResults):
+        success_count = 0
+        fail_count = 0
+        print '\n'
+        print '------------------- Test Results ------------------------'
+        for (conf_name, result) in testResults.iteritems():
+            if int(result['expected']) == int(result['actual']):
+                print 'Test for configuration %s has succeeded' % conf_name
+                success_count += 1
+            else:
+                print 'Test for configuration %s has failed' % conf_name
+                fail_count += 1
+
+        print '------------------- Summary -----------------------------'
+        print 'Of %i tests %i failed, %i succeeded' % (len(testResults),
+                                                       fail_count,
+                                                       success_count)
+        print '---------------------------------------------------------'
+    
+
+    def clean(self):
+        self._kill()
+
+        
+if __name__ == '__main__':
+    src_path = os.environ["PWD"]
+    print "SOURCE PATH ==>" , src_path
+    test = None
+    try:
+        test = Launcher(src_path)
+        result = test.run('main')
+        test.clean()
+        test.printTestResults(result)
+        
+    except:
+        if test is not None:
+            test.clean()
+        raise