Przeglądaj źródła

pre-authentication

Jonathan Turner 9 lat temu
rodzic
commit
31db7a56a5

+ 67 - 47
client/ASExchange.go

@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"github.com/jcmturner/gokrb5/crypto"
 	"github.com/jcmturner/gokrb5/iana/errorcode"
+	"github.com/jcmturner/gokrb5/iana/keyusage"
 	"github.com/jcmturner/gokrb5/iana/patype"
 	"github.com/jcmturner/gokrb5/messages"
 	"github.com/jcmturner/gokrb5/types"
@@ -16,70 +17,89 @@ func (cl *Client) ASExchange() error {
 	if !cl.IsConfigured() {
 		return errors.New("Client is not configured correctly.")
 	}
-	a := messages.NewASReq(cl.Config, cl.Credentials.CName)
-	b, err := a.Marshal()
+	ASReq := messages.NewASReq(cl.Config, cl.Credentials.CName)
+	err := setPAData(cl, &ASReq)
 	if err != nil {
-		return fmt.Errorf("Error marshalling AS_REQ: %v", err)
+		return fmt.Errorf("Error setting AS_REQ PAData: %v", err)
 	}
-	rb, err := cl.SendToKDC(b)
+	b, err := ASReq.Marshal()
 	if err != nil {
-		return fmt.Errorf("Error sending AS_REQ to KDC: %v", err)
+		return fmt.Errorf("Error marshalling AS_REQ: %v", err)
 	}
-	var ar messages.ASRep
-	err = ar.Unmarshal(rb)
+
+	var ASRep messages.ASRep
+
+	rb, err := cl.SendToKDC(b)
 	if err != nil {
-		//A KRBError may have been returned instead.
-		var krberr messages.KRBError
-		err = krberr.Unmarshal(rb)
-		if err != nil {
-			return fmt.Errorf("Could not unmarshal data returned from KDC: %v", err)
-		}
-		if krberr.ErrorCode == errorcode.KDC_ERR_PREAUTH_REQUIRED {
-			paTSb, err := types.GetPAEncTSEncAsnMarshalled()
+		if e, ok := err.(messages.KRBError); ok && e.ErrorCode == errorcode.KDC_ERR_PREAUTH_REQUIRED {
+			// From now on assume this client will need to do this pre-auth and set the PAData
+			cl.GoKrb5Conf.Assume_PA_ENC_TIMESTAMP_Required = true
+			err = setPAData(cl, &ASReq)
 			if err != nil {
-				return fmt.Errorf("Error creating PAEncTSEnc for Pre-Authentication: %v", err)
+				return fmt.Errorf("Error setting AS_REQ PAData for pre-authentication required: %v", err)
 			}
-			sort.Sort(sort.Reverse(sort.IntSlice(cl.Config.LibDefaults.Default_tkt_enctype_ids)))
-			etype, err := crypto.GetEtype(cl.Config.LibDefaults.Default_tkt_enctype_ids[0])
+			b, err := ASReq.Marshal()
 			if err != nil {
-				return fmt.Errorf("Error creating etype: %v", err)
+				return fmt.Errorf("Error marshalling AS_REQ with PAData: %v", err)
 			}
-			//paEncTS, err := crypto.GetEncryptedData(paTSb, etype, cl.Config.LibDefaults.Default_realm, cl.Credentials.Username, cl.Credentials.Keytab, 1)
-			key, err := cl.Credentials.Keytab.GetEncryptionKey(cl.Credentials.CName.NameString, cl.Config.LibDefaults.Default_realm, 1, etype.GetETypeID())
-			paEncTS, err := crypto.GetEncryptedData(paTSb, key, 0, 1)
-			if err != nil {
-				return fmt.Errorf("Error encrypting pre-authentication timestamp: %v", err)
-			}
-			pa := types.PAData{
-				PADataType:  patype.PA_ENC_TIMESTAMP,
-				PADataValue: paEncTS.Cipher,
-			}
-			a.PAData = append(a.PAData, pa)
-			b, err := a.Marshal()
-			if err != nil {
-				return fmt.Errorf("Error marshalling AS_REQ: %v", err)
-			}
-			rb, err := cl.SendToKDC(b)
+			rb, err = cl.SendToKDC(b)
 			if err != nil {
 				return fmt.Errorf("Error sending AS_REQ to KDC: %v", err)
 			}
-			err = ar.Unmarshal(rb)
-			if err != nil {
-				return fmt.Errorf("Could not unmarshal data returned from KDC: %v", err)
-			}
+		} else {
+			return fmt.Errorf("Error sending AS_REQ to KDC: %v", err)
 		}
-		return krberr
 	}
-	if ok, err := ar.IsValid(cl.Config, cl.Credentials, a); !ok {
+	err = ASRep.Unmarshal(rb)
+	if err != nil {
+		return fmt.Errorf("Could not unmarshal AS_REP data returned from KDC: %v", err)
+	}
+	if ok, err := ASRep.IsValid(cl.Config, cl.Credentials, ASReq); !ok {
 		return fmt.Errorf("AS_REP is not valid: %v", err)
 	}
 	cl.Session = &Session{
-		AuthTime:             ar.DecryptedEncPart.AuthTime,
-		EndTime:              ar.DecryptedEncPart.EndTime,
-		RenewTill:            ar.DecryptedEncPart.RenewTill,
-		TGT:                  ar.Ticket,
-		SessionKey:           ar.DecryptedEncPart.Key,
-		SessionKeyExpiration: ar.DecryptedEncPart.KeyExpiration,
+		AuthTime:             ASRep.DecryptedEncPart.AuthTime,
+		EndTime:              ASRep.DecryptedEncPart.EndTime,
+		RenewTill:            ASRep.DecryptedEncPart.RenewTill,
+		TGT:                  ASRep.Ticket,
+		SessionKey:           ASRep.DecryptedEncPart.Key,
+		SessionKeyExpiration: ASRep.DecryptedEncPart.KeyExpiration,
+	}
+	return nil
+}
+
+func setPAData(cl *Client, ASReq *messages.ASReq) error {
+	if !cl.GoKrb5Conf.Disable_PA_FX_FAST {
+		pa := types.PAData{PADataType: patype.PA_REQ_ENC_PA_REP}
+		ASReq.PAData = append(ASReq.PAData, pa)
+	}
+	if cl.GoKrb5Conf.Assume_PA_ENC_TIMESTAMP_Required {
+		paTSb, err := types.GetPAEncTSEncAsnMarshalled()
+		if err != nil {
+			return fmt.Errorf("Error creating PAEncTSEnc for Pre-Authentication: %v", err)
+		}
+		sort.Sort(sort.Reverse(sort.IntSlice(cl.Config.LibDefaults.Default_tkt_enctype_ids)))
+		etype, err := crypto.GetEtype(cl.Config.LibDefaults.Default_tkt_enctype_ids[0])
+		if err != nil {
+			return fmt.Errorf("Error creating etype: %v", err)
+		}
+		key, err := cl.Credentials.Keytab.GetEncryptionKey(cl.Credentials.CName.NameString, cl.Config.LibDefaults.Default_realm, 1, etype.GetETypeID())
+		if err != nil {
+			return fmt.Errorf("Error getting key from keytab in credentials: %v", err)
+		}
+		paEncTS, err := crypto.GetEncryptedData(paTSb, key, keyusage.AS_REQ_PA_ENC_TIMESTAMP, 1)
+		if err != nil {
+			return fmt.Errorf("Error encrypting pre-authentication timestamp: %v", err)
+		}
+		pb, err := paEncTS.Marshal()
+		if err != nil {
+			return fmt.Errorf("Error marshaling the PAEncTSEnc encrypted data: %v", err)
+		}
+		pa := types.PAData{
+			PADataType:  patype.PA_ENC_TIMESTAMP,
+			PADataValue: pb,
+		}
+		ASReq.PAData = append(ASReq.PAData, pa)
 	}
 	return nil
 }

+ 9 - 0
client/client.go

@@ -11,16 +11,24 @@ import (
 type Client struct {
 	Credentials *credentials.Credentials
 	Config      *config.Config
+	GoKrb5Conf  *Config
 	Session     *Session
 	Cache       *Cache
 }
 
+// GoKRB5 specific client configurations.
+type Config struct {
+	Disable_PA_FX_FAST               bool
+	Assume_PA_ENC_TIMESTAMP_Required bool
+}
+
 // Create a new client with a password credential.
 func NewClientWithPassword(username, realm, password string) Client {
 	creds := credentials.NewCredentials(username, realm)
 	return Client{
 		Credentials: creds.WithPassword(password),
 		Config:      config.NewConfig(),
+		GoKrb5Conf:  &Config{},
 		Session:     &Session{},
 		Cache:       NewCache(),
 	}
@@ -32,6 +40,7 @@ func NewClientWithKeytab(username, realm string, kt keytab.Keytab) Client {
 	return Client{
 		Credentials: creds.WithKeytab(kt),
 		Config:      config.NewConfig(),
+		GoKrb5Conf:  &Config{},
 		Session:     &Session{},
 		Cache:       NewCache(),
 	}

+ 13 - 0
client/client_integration_test.go

@@ -64,6 +64,19 @@ func TestClient_FailedLogin(t *testing.T) {
 	}
 }
 
+func TestClient_SuccessfulLogin_UserRequiringPreAuth(t *testing.T) {
+	b, err := hex.DecodeString(testdata.TESTUSER2_KEYTAB)
+	kt, _ := keytab.Parse(b)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
+	cl := NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt)
+	cl.WithConfig(c)
+
+	err = cl.Login()
+	if err != nil {
+		t.Fatalf("Error on login: %v\n", err)
+	}
+}
+
 func TestClient_NetworkTimeout(t *testing.T) {
 	b, err := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
 	kt, _ := keytab.Parse(b)

+ 26 - 14
client/network.go

@@ -36,48 +36,60 @@ func (cl *Client) SendToKDC(b []byte) ([]byte, error) {
 		//1 means we should always use TCP
 		rb, errtcp := sendTCP(kdc, b)
 		if errtcp != nil {
-			return rb, fmt.Errorf("Failed to communicate with KDC %v via TDP (%v)", kdc, errtcp)
+			if e, ok := errtcp.(messages.KRBError); ok {
+				return rb, e
+			}
+			return rb, fmt.Errorf("Failed to communicate with KDC %v via TCP (%v)", kdc, errtcp)
 		}
 		if len(rb) < 1 {
 			return rb, fmt.Errorf("No response data from KDC %v", kdc)
 		}
-		return checkForKRBError(rb)
+		return rb, nil
 	}
 	if len(b) <= cl.Config.LibDefaults.Udp_preference_limit {
 		//Try UDP first, TCP second
 		rb, errudp := sendUDP(kdc, b)
 		if errudp != nil {
+			if e, ok := errudp.(messages.KRBError); ok && e.ErrorCode != errorcode.KRB_ERR_RESPONSE_TOO_BIG {
+				// Got a KRBError from KDC
+				// If this is not a KRB_ERR_RESPONSE_TOO_BIG we will return immediately otherwise will try TCP.
+				return rb, e
+			}
+			// Try TCP
 			rb, errtcp := sendTCP(kdc, b)
 			if errtcp != nil {
-				return rb, fmt.Errorf("Failed to communicate with KDC %v via UDP (%v) and then via TDP (%v)", kdc, errudp, errtcp)
-			}
-		}
-		var KRBErr messages.KRBError
-		if err := KRBErr.Unmarshal(rb); err == nil {
-			if KRBErr.ErrorCode == errorcode.KRB_ERR_RESPONSE_TOO_BIG {
-				rb, errtcp := sendTCP(kdc, b)
-				if errtcp != nil {
-					return rb, fmt.Errorf("Failed to communicate with KDC %v. Response too big for UDP and errored when using TCP: %v ", kdc, errtcp)
+				if e, ok := errtcp.(messages.KRBError); ok {
+					// Got a KRBError
+					return rb, e
 				}
+				return rb, fmt.Errorf("Failed to communicate with KDC %v. Attempts made with UDP (%v) and then TCP (%v)", kdc, errudp, errtcp)
 			}
 		}
 		if len(rb) < 1 {
 			return rb, fmt.Errorf("No response data from KDC %v", kdc)
 		}
-		return checkForKRBError(rb)
+		return rb, nil
 	}
 	//Try TCP first, UDP second
 	rb, errtcp := sendTCP(kdc, b)
 	if errtcp != nil {
+		if e, ok := errtcp.(messages.KRBError); ok {
+			// Got a KRBError from KDC so returning and not trying UDP.
+			return rb, e
+		}
 		rb, errudp := sendUDP(kdc, b)
 		if errudp != nil {
-			return rb, fmt.Errorf("Failed to communicate with KDC %v via TCP (%v) and then via UDP (%v)", kdc, errtcp, errudp)
+			if e, ok := errudp.(messages.KRBError); ok {
+				// Got a KRBError
+				return rb, e
+			}
+			return rb, fmt.Errorf("Failed to communicate with KDC %v. Attempts made with TCP (%v) and then UDP (%v)", kdc, errtcp, errudp)
 		}
 	}
 	if len(rb) < 1 {
 		return rb, fmt.Errorf("No response data from KDC %v", kdc)
 	}
-	return checkForKRBError(rb)
+	return rb, nil
 }
 
 // Send the bytes to the KDC over UDP.

+ 28 - 0
example.go

@@ -32,6 +32,7 @@ func main() {
 	s := httpServer()
 	defer s.Close()
 	httpRequest(s.URL)
+	//httpRequest2(s.URL)
 	//httpRequest("http://host.test.gokrb5/index.html")
 }
 
@@ -62,6 +63,33 @@ func httpRequest(url string) {
 	fmt.Fprintf(os.Stdout, "Response Body:\n%s\n", content)
 }
 
+func httpRequest2(url string) {
+	l := log.New(os.Stderr, "GOKRB5 Client: ", log.Ldate|log.Ltime|log.Lshortfile)
+	b, err := hex.DecodeString(testdata.TESTUSER2_KEYTAB)
+	kt, _ := keytab.Parse(b)
+	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
+	cl := client.NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt)
+	cl.WithConfig(c)
+
+	err = cl.Login()
+	if err != nil {
+		l.Printf("Error on AS_REQ: %v\n", err)
+	}
+	cl.EnableAutoSessionRenewal()
+	r, _ := http.NewRequest("GET", url, nil)
+	err = cl.SetSPNEGOHeader(r, "HTTP/host.test.gokrb5")
+	if err != nil {
+		l.Printf("Error setting client SPNEGO header: %v", err)
+	}
+	httpResp, err := http.DefaultClient.Do(r)
+	if err != nil {
+		l.Printf("Request error: %v\n", err)
+	}
+	fmt.Fprintf(os.Stdout, "Response Code: %v\n", httpResp.StatusCode)
+	content, _ := ioutil.ReadAll(httpResp.Body)
+	fmt.Fprintf(os.Stdout, "Response Body:\n%s\n", content)
+}
+
 func httpServer() *httptest.Server {
 	l := log.New(os.Stderr, "GOKRB5 Service: ", log.Ldate|log.Ltime|log.Lshortfile)
 	b, _ := hex.DecodeString(testdata.HTTP_KEYTAB)

+ 1 - 1
iana/errorcode/constants.go

@@ -107,7 +107,7 @@ var errorcodeLookup = map[int]string{
 	KDC_ERR_SERVICE_NOTYET:                "KDC_ERR_SERVICE_NOTYET Server not yet valid; try again later",
 	KDC_ERR_KEY_EXPIRED:                   "KDC_ERR_KEY_EXPIRED Password has expired; change password to reset",
 	KDC_ERR_PREAUTH_FAILED:                "KDC_ERR_PREAUTH_FAILED Pre-authentication information was invalid",
-	KDC_ERR_PREAUTH_REQUIRED:              "KDC_ERR_PREAUTH_REQUIRED Additional pre- authentication required",
+	KDC_ERR_PREAUTH_REQUIRED:              "KDC_ERR_PREAUTH_REQUIRED Additional pre-authentication required",
 	KDC_ERR_SERVER_NOMATCH:                "KDC_ERR_SERVER_NOMATCH Requested server and ticket don't match",
 	KDC_ERR_MUST_USE_USER2USER:            "KDC_ERR_MUST_USE_USER2USER Server principal valid for  user2user only",
 	KDC_ERR_PATH_NOT_ACCEPTED:             "KDC_ERR_PATH_NOT_ACCEPTED KDC Policy rejects transited path",

+ 1 - 6
messages/KDCReq.go

@@ -81,11 +81,6 @@ type KDCReqBody struct {
 
 // Generate a new KRB_AS_REQ struct.
 func NewASReq(c *config.Config, cname types.PrincipalName) ASReq {
-	pas := types.PADataSequence{
-		types.PAData{
-			PADataType: patype.PA_REQ_ENC_PA_REP,
-		},
-	}
 	nonce := int(rand.Int31())
 	t := time.Now().UTC()
 
@@ -93,7 +88,7 @@ func NewASReq(c *config.Config, cname types.PrincipalName) ASReq {
 		KDCReqFields{
 			PVNO:    iana.PVNO,
 			MsgType: msgtype.KRB_AS_REQ,
-			PAData:  pas,
+			PAData:  types.PADataSequence{},
 			ReqBody: KDCReqBody{
 				KDCOptions: c.LibDefaults.Kdc_default_options,
 				Realm:      c.LibDefaults.Default_realm,

+ 2 - 0
testdata/test_vectors.go

@@ -100,6 +100,8 @@ var TestVectors = map[string]string{
 const (
 	TESTUSER1_KEYTAB      = "05020000003b0001000b544553542e474f4b52423500097465737475736572310000000158ee757c0100110010698c4df8e9f60e7eea5a21bf4526ad25000000010000004b0001000b544553542e474f4b52423500097465737475736572310000000158ee757c0100120020bbdc430aab7e2d4622a0b6951481453b0962e9db8e2f168942ad175cda6d9de900000001"
 	TESTUSER1_WRONGPASSWD = "0502000000370001000b544553542e474f4b52423500097465737475736572310000000158ef4bc5010011001039a9a382153105f8708e80f93382654e000000470001000b544553542e474f4b52423500097465737475736572310000000158ef4bc60100120020fc5bb940d6075214e0c6fc0456ce68c33306094198a927b4187d7cf3f4aea50d"
+	TESTUSER2_KEYTAB      = "05020000003b0001000b544553542e474f4b52423500097465737475736572320000000158ee75db010011001086824c55ff5de30386dd83dc62b44bb7000000010000004b0001000b544553542e474f4b52423500097465737475736572320000000158ee75db0100120020d8ed27f96be76fd5b281ee9f8029db93cc5fb06c7eb3be9ee753106d3488fa9200000001"
+	TESTUSER3_KEYTAB      = "05020000003b0001000b544553542e474f4b52423500097465737475736572330000000158ee76010100110010220789f5cf68e44a852c73b1e3729efc000000010000004b0001000b544553542e474f4b52423500097465737475736572330000000158ee760101001200205e1b7287f78f3f88c9eefe92c08ec1613f35d72bc6ee2c2e1c5cb6fb9d8b058000000001"
 	HTTP_KEYTAB           = "0502000000480002000b544553542e474f4b5242350004485454500010686f73742e746573742e676f6b7262350000000158ee7636010011001057a7754c70c4d85c155c718c2f1292b000000001000000580002000b544553542e474f4b5242350004485454500010686f73742e746573742e676f6b7262350000000158ee763601001200209cad00bbc72d703258e911dc18e6d5487cf737bf67fd111f0c2463ad6033bf5100000001"
 	TEST_AS_REQ           = "6a81a63081a3a103020105a20302010aa30e300c300aa10402020095a2020400a48186308183a00703050040000010a1163014a003020101a10d300b1b09746573747573657231a20d1b0b544553542e474f4b524235a320301ea003020102a11730151b066b72627467741b0b544553542e474f4b524235a511180f32303137303232303134323530315aa70602040f6755a6a814301202011202011102011002011702011902011a"
 	TEST_AS_REP           = "6b8202f3308202efa003020105a10302010ba22e302c302aa103020113a2230421301f301da003020112a1161b14544553542e474f4b524235746573747573657231a30d1b0b544553542e474f4b524235a4163014a003020101a10d300b1b09746573747573657231a582015a6182015630820152a003020105a10d1b0b544553542e474f4b524235a220301ea003020102a11730151b066b72627467741b0b544553542e474f4b524235a382011830820114a003020112a103020101a28201060482010264d3fa49d89b627ed471298846ff92cd8632f657c58fe25322a61fffa32bb7966dc4c44c86a81353def2a11c36c537191406a609147f424a63266c00d02bcc56a27b0969d86ff4352634be9e2a4ac0ad5a36b0b0a3d689f128c0afa97401796e88037a35ad19efaf31d1ed4f3213769c03a58bc90ffac2051db152c0ed0809ad05ffb03aa3afaf731ed85f7a73020cb72355e0de27842dcf7eae3de9f7c14aa237edb25153b217ef3693373bc3cacbebe406910ff9ae9d00b7b08f726cb29a213cb9ad51ba80a8c24fa4b6692a445686889702cfa6ea749bac03e27e982407aca623fbd48586bcf566cfe87e1d9f17a74b1315669c16480f93e9d8782e71a8f11000a682012c30820128a003020112a282011f0482011b99b86153c0393c0e4130628f3e1e0f0a1f034e7e61a111b7fad15884e231c8fd8727e0bc945c9b35be20c57d057c8b09b0de74c53fb38cc15c9a2d483023fc369f5bde4da7324b4732b5a3d9504d92f67026aaa01df4f0138245d2ccb1c5a4014804cf295c7e7e56a867e6cf0c534f667f32da7aa5e700af1461764f1c276a8ff0fbee0e99322fe2059d2321853be09d0956c3afcfd07e3e702646a4678926a77bea20d9aaf3086b6d384821c81900af9013a3519f0e50eab6e1491d72e4ee17c2a44441b2ebc8a796cc3d876e328347dce65f61104e14d4c31532885776c9c8a70186b8b39f928972945c98bd60381ead5448e7ebe93fea308054287ac34b0583b4b9b5e43c5f8518d693ba9eb48a219c27344466b3c693a70462"

+ 3 - 34
testenv/krb5kdc-vagrant/kdc-setup.sh

@@ -8,7 +8,6 @@ ADMIN_USERNAME=adminuser
 HOST_PRINCIPALS="kdc.test.gokrb5 host.test.gokrb5"
 SPNs="HTTP/host.test.gokrb5"
 KEYTABS="http.testtab!0:48!HTTP/host.test.gokrb5"
-INITIAL_USERS="testuser1 testuser2 testuser3"
 
 cp /vagrant/krb5.conf /etc/krb5.conf
 cp /var/kerberos/krb5kdc/kdc.conf /var/kerberos/krb5kdc/kdc.conf-old
@@ -32,8 +31,6 @@ create_entropy() {
 
 create_entropy &
 
-#Check and initialise if needs be
-if [ ! -f /opt/krb5/data/principal ]; then
   echo "Kerberos initialisation required. Creating database for ${REALM} ..."
   echo "This can take a long time if there is little entropy. A process has been started to create some."
   MASTER_PASSWORD=$(echo $RANDOM$RANDOM$RANDOM | md5sum | awk '{print $1}')
@@ -64,40 +61,12 @@ if [ ! -f /opt/krb5/data/principal ]; then
     done
   fi
 
-  if [ ! -z "$INITIAL_USERS" ]; then
-    for user in $INITIAL_USERS
-    do
-      /usr/sbin/kadmin.local -q "add_principal -pw passwordvalue -kvno 1 $user"
-      #/usr/sbin/kadmin.local -q "ktadd -k ${KEYTAB_DIR}/${user}.testtab $user"
-      echo "User $user added to kerberos database. To update password: sudo /usr/sbin/kadmin.local -q \"change_password $user\""
-    done
-  fi
+  /usr/sbin/kadmin.local -q "add_principal -pw passwordvalue -kvno 1 testuser1"
+  /usr/sbin/kadmin.local -q "add_principal +requires_preauth -pw passwordvalue -kvno 1 testuser2"
+  /usr/sbin/kadmin.local -q "add_principal -pw passwordvalue -kvno 1 testuser3"
 
-#  if [ ! -z "$KEYTABS" ]; then
-#    echo "Exporting keytabs"
-#    OLDIFS=$IFS
-#    IFS=";"
-#    KEYTAB=($KEYTABS)
-#    for keytabInst in ${KEYTAB[@]}
-#    do
-#      keytabFileName=$(echo $keytabInst | cut -d! -f1)
-#      permissions=$(echo $keytabInst | cut -d! -f2)
-#      principals=$(echo $keytabInst | cut -d! -f3)
-#      IFS=" "
-#      for princ in $principals
-#      do
-#        /usr/sbin/kadmin.local -q "ktadd -k ${KEYTAB_DIR}/${keytabFileName} $princ"
-#        echo "Add principal ${princ} to ${keytabFileName}"
-#      done
-#      IFS=";"
-#      chown $permissions ${KEYTAB_DIR}/${keytabFileName}
-#      chmod 660 ${KEYTAB_DIR}/${keytabFileName}
-#    done
-#    IFS=$OLDIFS
-#  fi
 
   echo "Kerberos initialisation complete"
-fi