[DIRKRB-277]-Extract Kadmin API.
diff --git a/kerby-kerb/kerb-admin/pom.xml b/kerby-kerb/kerb-admin/pom.xml
index 76469f5..1b0cec4 100644
--- a/kerby-kerb/kerb-admin/pom.xml
+++ b/kerby-kerb/kerb-admin/pom.xml
@@ -39,7 +39,12 @@
     </dependency>
     <dependency>
       <groupId>org.apache.kerby</groupId>
-      <artifactId>kerb-crypto</artifactId>
+      <artifactId>kerb-server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.kerby</groupId>
+      <artifactId>kerb-util</artifactId>
       <version>${project.version}</version>
     </dependency>
   </dependencies>
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Kadmin.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Kadmin.java
index b4dd6ab..63589f9 100644
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Kadmin.java
+++ b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Kadmin.java
@@ -19,10 +19,258 @@
  */
 package org.apache.kerby.kerberos.kerb.admin;
 
+import org.apache.kerby.KOptions;
+import org.apache.kerby.config.Config;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
+import org.apache.kerby.kerberos.kerb.identity.IdentityService;
+import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
+import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
+import org.apache.kerby.kerberos.kerb.keytab.Keytab;
+import org.apache.kerby.kerberos.kerb.keytab.KeytabEntry;
+import org.apache.kerby.kerberos.kerb.server.BackendConfig;
+import org.apache.kerby.kerberos.kerb.server.KdcConfig;
+import org.apache.kerby.kerberos.kerb.server.KdcConfigKey;
+import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
+import org.apache.kerby.kerberos.kerb.spec.base.EncryptionType;
+import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
 /**
  * Server side admin facilities.
  */
 public class Kadmin {
 
+    private KdcConfig kdcConfig;
+    private IdentityBackend backend;
 
+    public Kadmin(KdcConfig kdcConfig, Config backendConfig) {
+        this.kdcConfig = kdcConfig;
+        backend = getBackend(backendConfig);
+    }
+
+    public Kadmin(Config backendConfig) {
+        backend = getBackend(backendConfig);
+    }
+
+    /**
+     * Set KDC config.
+     * @param kdcConfig
+     */
+    public void setKdcConfig(KdcConfig kdcConfig) {
+        this.kdcConfig = kdcConfig;
+    }
+
+    /**
+     * Set backend config.
+     * @param backendConfig
+     */
+    public void setBackendConfig(BackendConfig backendConfig) {
+        backend = getBackend(backendConfig);
+    }
+
+    /**
+     * Get identity service.
+     * @return IdentityService
+     */
+    public IdentityService getIdentityService() {
+        return backend;
+    }
+
+    /**
+     * Init the identity backend from backend configuration.
+     */
+    public IdentityBackend getBackend(Config backendConfig) {
+        String backendClassName = backendConfig.getString(
+                KdcConfigKey.KDC_IDENTITY_BACKEND);
+        if (backendClassName == null) {
+            throw new RuntimeException("Can not find the IdentityBackend class");
+        }
+
+        Class<?> backendClass = null;
+        try {
+            backendClass = Class.forName(backendClassName);
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException("Failed to load backend class: "
+                    + backendClassName);
+        }
+
+        IdentityBackend backend;
+        try {
+            backend = (IdentityBackend) backendClass.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new RuntimeException("Failed to create backend: "
+                    + backendClassName);
+        }
+
+        backend.setConfig(backendConfig);
+        backend.initialize();
+        return backend;
+    }
+
+    public void addPrincipal(String principal, String password, KOptions kOptions)
+        throws KrbException {
+
+        KrbIdentity identity = createIdentity(principal, password, kOptions);
+        try {
+            backend.addIdentity(identity);
+        } catch (RuntimeException e) {
+            throw new KrbException("Fail to add principal.", e);
+        }
+    }
+
+    private KrbIdentity createIdentity(String principal, String password, KOptions kOptions)
+        throws KrbException {
+        KrbIdentity kid = new KrbIdentity(principal);
+        kid.setCreatedTime(KerberosTime.now());
+        if(kOptions.contains(KadminOption.EXPIRE)) {
+            Date date = kOptions.getDateOption(KadminOption.EXPIRE);
+            kid.setExpireTime(new KerberosTime(date.getTime()));
+        } else {
+            kid.setExpireTime(KerberosTime.NEVER);
+        }
+        if(kOptions.contains(KadminOption.KVNO)) {
+            kid.setKeyVersion(kOptions.getIntegerOption(KadminOption.KVNO));
+        } else {
+            kid.setKeyVersion(1);
+        }
+        kid.setDisabled(false);
+        kid.setLocked(false);
+        kid.addKeys(generateKeys(kid.getPrincipalName(), password));
+
+        return kid;
+    }
+
+    private List<EncryptionKey> generateKeys(String principal, String password)
+        throws KrbException {
+        try {
+            return EncryptionUtil.generateKeys(principal, password, kdcConfig.getEncryptionTypes());
+        } catch (KrbException e) {
+            throw new KrbException("Failed to create keys", e);
+        }
+    }
+
+    public StringBuffer addEntryToKeytab(File keytabFile, String principalName)
+        throws KrbException {
+
+        //Get Identity
+        KrbIdentity identity = backend.getIdentity(principalName);
+        if (identity == null) {
+            throw new KrbException("Can not find the identity for pincipal " +
+                    principalName + ".");
+        }
+
+        StringBuffer resultSB = new StringBuffer();
+        Keytab keytab = loadKeytab(keytabFile);
+
+        //Add principal to keytab.
+        PrincipalName principal = identity.getPrincipal();
+        KerberosTime timestamp = new KerberosTime();
+        for (EncryptionType encType : identity.getKeys().keySet()) {
+            EncryptionKey ekey = identity.getKeys().get(encType);
+            int keyVersion = ekey.getKvno();
+            keytab.addEntry(new KeytabEntry(principal, timestamp, keyVersion, ekey));
+            resultSB.append("Entry for principal " + principalName +
+                    " with kvno " + keyVersion + ", encryption type " +
+                    encType.getName() + " added to keytab " +
+                    keytabFile.getAbsolutePath() + "\n");
+        }
+
+        //Store the keytab
+        try {
+            keytab.store(keytabFile);
+        } catch (IOException e) {
+            throw new KrbException("Fail to store the keytab!", e);
+        }
+        return resultSB;
+    }
+
+    private Keytab loadKeytab(File keytabFile) throws KrbException {
+        try {
+            if (!keytabFile.exists()) {
+                keytabFile.createNewFile();
+                return new Keytab();
+            }
+
+            return Keytab.loadKeytab(keytabFile);
+        } catch (IOException e) {
+            throw new KrbException("Fail to load keytab!", e);
+        }
+    }
+
+    public void deletePrincipal(String principal) throws KrbException {
+        try {
+            backend.deleteIdentity(principal);
+        } catch (RuntimeException e) {
+            throw new KrbException("Fail to delete Identity!", e);
+        }
+    }
+
+    public void modifyPrincipal(String principal, KOptions kOptions) throws KrbException {
+
+        KrbIdentity originIdentity = backend.getIdentity(principal);
+        if (originIdentity == null) {
+            throw new KrbException("Principal \"" +
+                originIdentity.getPrincipalName() + "\" does not exist.");
+        }
+        KrbIdentity identity = createUpdatedIdentity(originIdentity, kOptions);
+        backend.updateIdentity(identity);
+    }
+
+    protected KrbIdentity createUpdatedIdentity(KrbIdentity kid, KOptions kOptions) {
+        if (kOptions.contains(KadminOption.EXPIRE)) {
+            Date date = kOptions.getDateOption(KadminOption.EXPIRE);
+            kid.setExpireTime(new KerberosTime(date.getTime()));
+        }
+        if (kOptions.contains(KadminOption.DISABLED)) {
+            kid.setDisabled(kOptions.getBooleanOption(KadminOption.DISABLED));
+        }
+        if (kOptions.contains(KadminOption.LOCKED)) {
+            kid.setLocked(kOptions.getBooleanOption(KadminOption.LOCKED));
+        }
+        return kid;
+    }
+
+    public void renamePrincipal(String oldPrincipalName, String newPrincipalName)
+        throws KrbException {
+
+        KrbIdentity verifyIdentity = backend.getIdentity(newPrincipalName);
+        if(verifyIdentity != null) {
+            throw new KrbException("Principal \"" +
+                verifyIdentity.getPrincipalName() + "\" is already exist.");
+        }
+        KrbIdentity identity = backend.getIdentity(oldPrincipalName);
+        if (identity == null) {
+            throw new KrbException("Principal \"" +
+                oldPrincipalName + "\" does not exist.");
+        }
+        backend.deleteIdentity(oldPrincipalName);
+
+        identity.setPrincipalName(newPrincipalName);
+        identity.setPrincipal(new PrincipalName(newPrincipalName));
+        backend.addIdentity(identity);
+    }
+
+    public KrbIdentity getPrincipal(String princName) throws KrbException {
+        try {
+            KrbIdentity identity = backend.getIdentity(princName);
+            return identity;
+        } catch (RuntimeException e) {
+            throw new KrbException("Failed to get identity!", e);
+        }
+    }
+
+    public List<String> listPrincipal() throws KrbException {
+        try {
+            List<String> principalNames = backend.getIdentities();
+            return principalNames;
+        } catch (RuntimeException e) {
+            throw new KrbException("Failed to get identity!", e);
+        }
+    }
 }
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/tool/KadminOption.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
similarity index 97%
rename from kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/tool/KadminOption.java
rename to kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
index 34d0fec..7c7dcde 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/tool/KadminOption.java
+++ b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
@@ -17,7 +17,7 @@
  *  under the License.
  *
  */
-package org.apache.kerby.kerberos.tool.kadmin.tool;
+package org.apache.kerby.kerberos.kerb.admin;
 
 import org.apache.kerby.KOption;
 import org.apache.kerby.KOptionType;
diff --git a/kerby-tool/kdc-tool/pom.xml b/kerby-tool/kdc-tool/pom.xml
index a9eeda6..3b0c29f 100644
--- a/kerby-tool/kdc-tool/pom.xml
+++ b/kerby-tool/kdc-tool/pom.xml
@@ -46,6 +46,11 @@
         <artifactId>kerb-util</artifactId>
         <version>${project.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.kerby</groupId>
+        <artifactId>kerb-admin</artifactId>
+        <version>${project.version}</version>
+      </dependency>
     </dependencies>
 
     <profiles>
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/AddPrincipalExecutor.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/AddPrincipalExecutor.java
index 61a3b55..e646eda 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/AddPrincipalExecutor.java
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/AddPrincipalExecutor.java
@@ -22,19 +22,13 @@
 import org.apache.kerby.KOptions;
 import org.apache.kerby.config.Config;
 import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
-import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
+import org.apache.kerby.kerberos.kerb.admin.Kadmin;
+import org.apache.kerby.kerberos.kerb.admin.KadminOption;
 import org.apache.kerby.kerberos.kerb.server.KdcConfig;
-import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
-import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
-import org.apache.kerby.kerberos.tool.kadmin.tool.KadminOption;
 import org.apache.kerby.kerberos.tool.kadmin.tool.KadminTool;
 
 import java.io.Console;
 import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
 import java.util.Scanner;
 
 public class AddPrincipalExecutor implements KadminCommandExecutor{
@@ -91,7 +85,14 @@
             return;
         }
 
-        addPrincipal(principal, password);
+        Kadmin kadmin = new Kadmin(kdcConfig, backendConfig);
+
+        try {
+            kadmin.addPrincipal(principal, password, kOptions);
+            System.out.println("Principal \"" + principal + "\" created.");
+        } catch (KrbException e) {
+            System.err.println("Fail to add principal \"" + principal + "\"." + e.getMessage());
+        }
     }
 
     /**
@@ -138,46 +139,4 @@
         Arrays.fill(passwordChars, ' ');
         return password;
     }
-
-    private void addPrincipal(String principal, String password) {
-        IdentityBackend backend = KadminTool.getBackend(backendConfig);
-
-        KrbIdentity identity = createIdentity(principal, password);
-        try {
-            backend.addIdentity(identity);
-            System.out.println("Principal \"" + principal + "\" created.");
-        } catch (Exception e) {
-            System.err.println("Principal or policy already exists while creating \"" + principal + "\".");
-        }
-    }
-
-    protected KrbIdentity createIdentity(String principal, String password) {
-        KrbIdentity kid = new KrbIdentity(principal);
-        kid.setCreatedTime(KerberosTime.now());
-        if(kOptions.contains(KadminOption.EXPIRE)) {
-            Date date = kOptions.getDateOption(KadminOption.EXPIRE);
-            kid.setExpireTime(new KerberosTime(date.getTime()));
-        } else {
-            kid.setExpireTime(KerberosTime.NEVER);
-        }
-        if(kOptions.contains(KadminOption.KVNO)) {
-            kid.setKeyVersion(kOptions.getIntegerOption(KadminOption.KVNO));
-        } else {
-            kid.setKeyVersion(1);
-        }
-        kid.setDisabled(false);
-        kid.setLocked(false);
-
-        kid.addKeys(generateKeys(kid.getPrincipalName(), password));
-
-        return kid;
-    }
-
-    protected List<EncryptionKey> generateKeys(String principal, String password) {
-        try {
-            return EncryptionUtil.generateKeys(principal, password, kdcConfig.getEncryptionTypes());
-        } catch (KrbException e) {
-            throw new RuntimeException("Failed to create keys", e);
-        }
-    }
 }
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/DeletePrincipalExecutor.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/DeletePrincipalExecutor.java
index c363e82..5a53599 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/DeletePrincipalExecutor.java
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/DeletePrincipalExecutor.java
@@ -20,8 +20,8 @@
 package org.apache.kerby.kerberos.tool.kadmin.executor;
 
 import org.apache.kerby.config.Config;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
-import org.apache.kerby.kerberos.tool.kadmin.tool.KadminTool;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.admin.Kadmin;
 
 import java.io.Console;
 import java.util.Scanner;
@@ -51,8 +51,9 @@
         parseOptions(commands);
         String principal = commands[commands.length - 1];
 
+        Kadmin kadmin = new Kadmin(backendConfig);
         if (force) {
-            deletePrincipal(principal);
+            deletePrincipal(kadmin, principal);
         } else {
             String reply;
             Console console = System.console();
@@ -67,7 +68,7 @@
                 reply = getReply(console, prompt);
             }
             if (reply.equals("yes") || reply.equals("YES") || reply.equals("y") || reply.equals("Y")) {
-                deletePrincipal(principal);
+                deletePrincipal(kadmin, principal);
             } else if (reply.equals("no") || reply.equals("NO") || reply.equals("n") || reply.equals("N")) {
                 System.out.println("Pincipal \"" + principal + "\"  not deleted." );
             } else {
@@ -76,6 +77,15 @@
         }
     }
 
+    private void deletePrincipal(Kadmin kadmin, String principal) {
+        try {
+            kadmin.deletePrincipal(principal);
+            System.out.println("Principal \"" + principal + "\" deleted.");
+        } catch (KrbException e) {
+            System.err.println("Fail to delete principal \"" + principal + "\" ." + e.getMessage());
+        }
+    }
+
     private String getReply(Scanner scanner, String prompt) {
         System.out.println(prompt);
         return scanner.nextLine().trim();
@@ -92,14 +102,4 @@
             force = true;
         }
     }
-
-    private void deletePrincipal(String principal) {
-        IdentityBackend backend = KadminTool.getBackend(backendConfig);
-        try {
-            backend.deleteIdentity(principal);
-            System.out.println("Principal \"" + principal + "\" deleted.");
-        } catch (Exception e) {
-            System.err.println("Principal \"" + principal + "\" fail to delete." + e.getMessage());
-        }
-    }
 }
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/GetPrincipalExcutor.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/GetPrincipalExcutor.java
index 06e8b53..0c97da2 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/GetPrincipalExcutor.java
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/GetPrincipalExcutor.java
@@ -20,11 +20,11 @@
 package org.apache.kerby.kerberos.tool.kadmin.executor;
 
 import org.apache.kerby.config.Config;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.admin.Kadmin;
 import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
 import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
 import org.apache.kerby.kerberos.kerb.spec.base.EncryptionType;
-import org.apache.kerby.kerberos.tool.kadmin.tool.KadminTool;
 
 import java.util.Map;
 
@@ -47,8 +47,13 @@
         }
 
         String princName = commands[commands.length - 1];
-        IdentityBackend backend = KadminTool.getBackend(backendConfig);
-        KrbIdentity identity = backend.getIdentity(princName);
+        Kadmin kadmin = new Kadmin(backendConfig);
+        KrbIdentity identity = null;
+        try {
+            identity = kadmin.getPrincipal(princName);
+        } catch (KrbException e) {
+            System.err.println("Fail to get principal:" + princName + ".");
+        }
 
         if (identity == null) {
             System.err.println(princName + "doesn't exist\n");
@@ -71,5 +76,4 @@
             System.out.println("key: " + keyType);
         }
     }
-
 }
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/KeytabAddExecutor.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/KeytabAddExecutor.java
index c27ce4a..e4a2770 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/KeytabAddExecutor.java
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/KeytabAddExecutor.java
@@ -20,18 +20,10 @@
 package org.apache.kerby.kerberos.tool.kadmin.executor;
 
 import org.apache.kerby.config.Config;
-import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
-import org.apache.kerby.kerberos.kerb.keytab.Keytab;
-import org.apache.kerby.kerberos.kerb.keytab.KeytabEntry;
-import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
-import org.apache.kerby.kerberos.kerb.spec.base.EncryptionKey;
-import org.apache.kerby.kerberos.kerb.spec.base.EncryptionType;
-import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
-import org.apache.kerby.kerberos.tool.kadmin.tool.KadminTool;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.admin.Kadmin;
 
 import java.io.File;
-import java.io.IOException;
 
 public class KeytabAddExecutor implements KadminCommandExecutor{
     private static final String USAGE =
@@ -75,57 +67,13 @@
         }
         File keytabFile = new File(keytabFileLocation);
 
-        addEntryToKeytab(keytabFile, principal);
-    }
-
-    private void addEntryToKeytab(File keytabFile, String principalName) {
-        IdentityBackend backend = KadminTool.getBackend(backendConfig);
-
-        //Get Identity
-        KrbIdentity identity = backend.getIdentity(principalName);
-        if (identity == null) {
-            System.err.println("Can not find the identity for pincipal " +
-                    principalName + ".");
-            return;
-        }
-
-        StringBuffer resultSB = new StringBuffer();
-        Keytab keytab = loadKeytab(keytabFile);
-
-        //Add principal to keytab.
-        PrincipalName principal = identity.getPrincipal();
-        KerberosTime timestamp = new KerberosTime();
-        for (EncryptionType encType : identity.getKeys().keySet()) {
-            EncryptionKey ekey = identity.getKeys().get(encType);
-            int keyVersion = ekey.getKvno();
-            keytab.addEntry(new KeytabEntry(principal, timestamp, keyVersion, ekey));
-            resultSB.append("Entry for principal " + principalName +
-                    " with kvno " + keyVersion + ", encryption type " +
-                    encType.getName() + " added to keytab " +
-                    keytabFile.getAbsolutePath() + "\n");
-        }
-
-        //Store the keytab
+        Kadmin kadmin = new Kadmin(backendConfig);
         try {
-            keytab.store(keytabFile);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        System.out.println(resultSB.toString());
-    }
-
-    private Keytab loadKeytab(File keytabFile) {
-        try {
-            if (!keytabFile.exists()) {
-                keytabFile.createNewFile();
-                return new Keytab();
-            }
-
-            return Keytab.loadKeytab(keytabFile);
-        } catch (IOException e) {
-            e.printStackTrace();
-            return new Keytab();
+        StringBuffer result = kadmin.addEntryToKeytab(keytabFile, principal);
+            System.out.println(result.toString());
+        } catch (KrbException e) {
+            System.err.println("Principal \"" + principal + "\" fail to add entry to keytab." +
+                e.getMessage());
         }
     }
-
 }
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/ListPrincipalExcutor.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/ListPrincipalExcutor.java
index 49f9f4f..ec5abe3 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/ListPrincipalExcutor.java
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/ListPrincipalExcutor.java
@@ -20,8 +20,8 @@
 package org.apache.kerby.kerberos.tool.kadmin.executor;
 
 import org.apache.kerby.config.Config;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
-import org.apache.kerby.kerberos.tool.kadmin.tool.KadminTool;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.admin.Kadmin;
 
 import java.util.List;
 
@@ -37,8 +37,14 @@
         String[] commands = input.split(" ");
         List<String> principalNames = null;
 
+
         if (commands.length == 1) {
-            principalNames = listPrincipal();
+            Kadmin kadmin = new Kadmin(backenConfig);
+            try {
+                principalNames = kadmin.listPrincipal();
+            } catch (KrbException e) {
+                System.err.print("Fail to list principal!" + e.getMessage());
+            }
         }
         System.out.println("Principals are listed:");
 
@@ -46,10 +52,4 @@
             System.out.println(principalName);
         }
     }
-
-    private List<String> listPrincipal() {
-        IdentityBackend backend = KadminTool.getBackend(backenConfig);
-        List<String> principalName = backend.getIdentities();
-        return principalName;
-    }
 }
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/ModifyPrincipalExecutor.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/ModifyPrincipalExecutor.java
index daa2849..bd2ee8c 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/ModifyPrincipalExecutor.java
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/ModifyPrincipalExecutor.java
@@ -22,15 +22,12 @@
 import org.apache.kerby.KOptionType;
 import org.apache.kerby.KOptions;
 import org.apache.kerby.config.Config;
-import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.admin.Kadmin;
 import org.apache.kerby.kerberos.kerb.server.KdcConfig;
-import org.apache.kerby.kerberos.kerb.spec.KerberosTime;
-import org.apache.kerby.kerberos.tool.kadmin.tool.KadminOption;
+import org.apache.kerby.kerberos.kerb.admin.KadminOption;
 import org.apache.kerby.kerberos.tool.kadmin.tool.KadminTool;
 
-import java.util.Date;
-
 public class ModifyPrincipalExecutor implements KadminCommandExecutor {
     private static final String USAGE = "Usage: modify_principal [options] principal\n" +
         "\toptions are:\n" +
@@ -59,7 +56,14 @@
             return;
         }
         parseOptions(commands);
-        modifyPrincipal(principal);
+        Kadmin kadmin = new Kadmin(kdcConfig, backendConfig);
+
+        try {
+            kadmin.modifyPrincipal(principal, kOptions);
+            System.out.println("Principal \"" + principal + "\" modified.");
+        } catch (KrbException e) {
+            System.err.println("Principal \"" + principal + "\" fail to modify." + e.getMessage());
+        }
     }
 
     private void parseOptions(String[] commands) {
@@ -100,31 +104,4 @@
             KadminTool.printUsage("missing principal name!", USAGE);
         }
     }
-
-    private void modifyPrincipal(String principal) {
-        IdentityBackend backend = KadminTool.getBackend(backendConfig);
-
-        KrbIdentity originIdentity = backend.getIdentity(principal);
-        KrbIdentity identity = createUpdatedIdentity(originIdentity);
-        try {
-            backend.updateIdentity(identity);
-            System.out.println("Principal \"" + principal + "\" modified.");
-        } catch (Exception e) {
-            System.err.println("Principal \"" + principal + "\" fail to modify." + e.getMessage());
-        }
-    }
-
-    protected KrbIdentity createUpdatedIdentity(KrbIdentity kid) {
-        if (kOptions.contains(KadminOption.EXPIRE)) {
-            Date date = kOptions.getDateOption(KadminOption.EXPIRE);
-            kid.setExpireTime(new KerberosTime(date.getTime()));
-        }
-        if (kOptions.contains(KadminOption.DISABLED)) {
-            kid.setDisabled(kOptions.getBooleanOption(KadminOption.DISABLED));
-        }
-        if (kOptions.contains(KadminOption.LOCKED)) {
-            kid.setLocked(kOptions.getBooleanOption(KadminOption.LOCKED));
-        }
-        return kid;
-    }
 }
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/RenamePrincipalExecutor.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/RenamePrincipalExecutor.java
index 17eaf34..bc0abe0 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/RenamePrincipalExecutor.java
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/executor/RenamePrincipalExecutor.java
@@ -21,10 +21,9 @@
 
 import org.apache.kerby.KOptions;
 import org.apache.kerby.config.Config;
-import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
-import org.apache.kerby.kerberos.kerb.spec.base.PrincipalName;
-import org.apache.kerby.kerberos.tool.kadmin.tool.KadminOption;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.admin.Kadmin;
+import org.apache.kerby.kerberos.kerb.admin.KadminOption;
 import org.apache.kerby.kerberos.tool.kadmin.tool.KadminTool;
 
 
@@ -56,13 +55,14 @@
         oldPrincipalName = commands[commands.length - 2];
         newPrincipalName = commands[commands.length - 1];
 
+        Kadmin kadmin = new Kadmin(backendConfig);
         if (kOptions.contains(KadminOption.FORCE)) {
-            renamePrincipal();
+            renamePrincipal(kadmin);
         } else {
             String prompt = "Are you sure want to rename the principal? (yes/no, YES/NO, y/n, Y/N) ";
             String reply = KadminTool.getReplay(prompt);
             if (reply.equals("yes") || reply.equals("YES") || reply.equals("y") || reply.equals("Y")) {
-                renamePrincipal();
+                renamePrincipal(kadmin);
             } else if (reply.equals("no") || reply.equals("NO") || reply.equals("n") || reply.equals("N")) {
                 System.out.println("Principal \"" + oldPrincipalName + "\"  not renamed." );
             } else {
@@ -71,30 +71,13 @@
         }
     }
 
-    private void renamePrincipal() {
-        IdentityBackend backend = KadminTool.getBackend(backendConfig);
-
-        KrbIdentity verifyIdentity = backend.getIdentity(newPrincipalName);
-        if(verifyIdentity != null) {
-            System.err.println("Principal rename failed! Principal \"" + verifyIdentity.getPrincipalName() + "\" is already exist.");
-            return;
-        }
-
+    public void renamePrincipal(Kadmin kadmin) {
         try {
-            KrbIdentity identity = backend.getIdentity(oldPrincipalName);
-            if(identity == null) {
-                System.err.println("Principal rename failed! Principal \"" + oldPrincipalName + "\" does not exist.");
-                return;
-            }
-            backend.deleteIdentity(oldPrincipalName);
-
-            identity.setPrincipalName(newPrincipalName);
-            identity.setPrincipal(new PrincipalName(newPrincipalName));
-            backend.addIdentity(identity);
-            System.out.println("Principal \"" + oldPrincipalName + "\" renamed to \"" + newPrincipalName + "\".");
-        } catch (Exception e) {
-            System.err.println("Principal rename failed! Exception happened.");
+            kadmin.renamePrincipal(oldPrincipalName, newPrincipalName);
+            System.out.println("Principal \"" + oldPrincipalName + "\" renamed to \"" +
+                newPrincipalName + "\".");
+        } catch (KrbException e) {
+            System.err.println("Principal rename failed! Exception happened." + e.getMessage());
         }
     }
-
 }
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/tool/KadminTool.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/tool/KadminTool.java
index 1a99fe9..72eb70a 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/tool/KadminTool.java
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/tool/KadminTool.java
@@ -21,45 +21,12 @@
 
 import org.apache.kerby.KOptionType;
 import org.apache.kerby.KOptions;
-import org.apache.kerby.config.Config;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
-import org.apache.kerby.kerberos.kerb.server.KdcConfigKey;
+import org.apache.kerby.kerberos.kerb.admin.KadminOption;
 
 import java.util.Scanner;
 
 public class KadminTool {
 
-    /**
-     * Init the identity backend from backend configuration.
-     */
-    public static IdentityBackend getBackend(Config backendConfig) {
-        String backendClassName = backendConfig.getString(
-                KdcConfigKey.KDC_IDENTITY_BACKEND);
-        if (backendClassName == null) {
-            throw new RuntimeException("Can not find the IdentityBackend class");
-        }
-
-        Class<?> backendClass = null;
-        try {
-            backendClass = Class.forName(backendClassName);
-        } catch (ClassNotFoundException e) {
-            throw new RuntimeException("Failed to load backend class: "
-                    + backendClassName);
-        }
-
-        IdentityBackend backend;
-        try {
-            backend = (IdentityBackend) backendClass.newInstance();
-        } catch (InstantiationException | IllegalAccessException e) {
-            throw new RuntimeException("Failed to create backend: "
-                    + backendClassName);
-        }
-
-        backend.setConfig(backendConfig);
-        backend.initialize();
-        return backend;
-    }
-
     public static void printUsage(String error, String USAGE) {
         System.err.println(error + "\n");
         System.err.println(USAGE);