You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pl...@apache.org on 2016/07/06 03:32:12 UTC

[4/6] directory-kerby git commit: DIRKRB-592 Merge kadmin-remote branch to trunk.

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/AdminServerUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/AdminServerUtil.java b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/AdminServerUtil.java
new file mode 100644
index 0000000..f48bf5b
--- /dev/null
+++ b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/AdminServerUtil.java
@@ -0,0 +1,165 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.kerberos.kerb.admin.server.kadmin;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.identity.backend.BackendConfig;
+import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
+import org.apache.kerby.kerberos.kerb.identity.backend.MemoryIdentityBackend;
+import org.apache.kerby.kerberos.kerb.server.KdcConfig;
+import org.apache.kerby.kerberos.kerb.transport.TransportPair;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+
+/**
+ * Admin Server utilities.
+ */
+public final class AdminServerUtil {
+
+    private AdminServerUtil() { }
+
+    /**
+     * Get adminServer configuration
+     * @param confDir configuration directory
+     * @return adminServer configuration
+     * @throws KrbException e.
+     */
+    public static AdminServerConfig getAdminServerConfig(File confDir) throws KrbException {
+        File adminServerConfFile = new File(confDir, "adminServer.conf");
+        if (adminServerConfFile.exists()) {
+            AdminServerConfig adminServerConfig = new AdminServerConfig();
+            try {
+                adminServerConfig.addKrb5Config(adminServerConfFile);
+            } catch (IOException e) {
+                throw new KrbException("Can not load the adminServer configuration file "
+                        + adminServerConfFile.getAbsolutePath());
+            }
+            return adminServerConfig;
+        }
+
+        return null;
+    }
+
+    /**
+     * Get kdc configuration
+     * @param confDir configuration directory
+     * @return kdc configuration
+     * @throws KrbException e.
+     */
+    public static KdcConfig getKdcConfig(File confDir) throws KrbException {
+        File kdcConfFile = new File(confDir, "kdc.conf");
+        if (kdcConfFile.exists()) {
+            KdcConfig kdcConfig = new KdcConfig();
+            try {
+                kdcConfig.addKrb5Config(kdcConfFile);
+            } catch (IOException e) {
+                throw new KrbException("Can not load the kdc configuration file "
+                    + kdcConfFile.getAbsolutePath());
+            }
+            return kdcConfig;
+        }
+
+        return null;
+    }
+
+    /**
+     * Get backend configuration
+     * @param confDir configuration directory
+     * @return backend configuration
+     * @throws KrbException e.
+     */
+    public static BackendConfig getBackendConfig(File confDir) throws KrbException {
+        File backendConfigFile = new File(confDir, "backend.conf");
+        if (backendConfigFile.exists()) {
+            BackendConfig backendConfig = new BackendConfig();
+            try {
+                backendConfig.addIniConfig(backendConfigFile);
+            } catch (IOException e) {
+                throw new KrbException("Can not load the backend configuration file "
+                        + backendConfigFile.getAbsolutePath());
+            }
+            return backendConfig;
+        }
+
+        return null;
+    }
+
+    /**
+     * Init the identity backend from backend configuration.
+     *
+     * @throws KrbException e.
+     * @param backendConfig backend configuration information
+     * @return backend
+     */
+    public static IdentityBackend getBackend(
+            BackendConfig backendConfig) throws KrbException {
+        String backendClassName = backendConfig.getString(
+                AdminServerConfigKey.KDC_IDENTITY_BACKEND, true);
+        if (backendClassName == null) {
+            backendClassName = MemoryIdentityBackend.class.getCanonicalName();
+        }
+
+        Class<?> backendClass;
+        try {
+            backendClass = Class.forName(backendClassName);
+        } catch (ClassNotFoundException e) {
+            throw new KrbException("Failed to load backend class: "
+                    + backendClassName);
+        }
+
+        IdentityBackend backend;
+        try {
+            backend = (IdentityBackend) backendClass.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new KrbException("Failed to create backend: "
+                    + backendClassName);
+        }
+
+        backend.setConfig(backendConfig);
+        backend.initialize();
+        return backend;
+    }
+
+    /**
+     * Get KDC network transport addresses according to KDC setting.
+     * @param setting kdc setting
+     * @return UDP and TCP addresses pair
+     * @throws KrbException e
+     */
+    public static TransportPair getTransportPair(
+            AdminServerSetting setting) throws KrbException {
+        TransportPair result = new TransportPair();
+
+        int tcpPort = setting.checkGetAdminTcpPort();
+        if (tcpPort > 0) {
+            result.tcpAddress = new InetSocketAddress(
+                    setting.getAdminHost(), tcpPort);
+        }
+        int udpPort = setting.checkGetAdminUdpPort();
+        if (udpPort > 0) {
+            result.udpAddress = new InetSocketAddress(
+                    setting.getAdminHost(), udpPort);
+        }
+
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/AbstractInternalAdminServer.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/AbstractInternalAdminServer.java b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/AbstractInternalAdminServer.java
new file mode 100644
index 0000000..ac71386
--- /dev/null
+++ b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/AbstractInternalAdminServer.java
@@ -0,0 +1,116 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *
+ */
+package org.apache.kerby.kerberos.kerb.admin.server.kadmin.impl;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.admin.server.kadmin.AdminServerConfig;
+import org.apache.kerby.kerberos.kerb.admin.server.kadmin.AdminServerSetting;
+import org.apache.kerby.kerberos.kerb.identity.CacheableIdentityService;
+import org.apache.kerby.kerberos.kerb.identity.IdentityService;
+import org.apache.kerby.kerberos.kerb.identity.backend.BackendConfig;
+import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
+import org.apache.kerby.kerberos.kerb.identity.backend.MemoryIdentityBackend;
+import org.apache.kerby.kerberos.kerb.server.KdcUtil;
+
+/**
+ * Abstract Kadmin admin implementation.
+ */
+public class AbstractInternalAdminServer implements InternalAdminServer {
+    private boolean started;
+    private final AdminServerConfig adminServerConfig;
+    private final BackendConfig backendConfig;
+    private final AdminServerSetting adminServerSetting;
+    private IdentityBackend backend;
+    private IdentityService identityService;
+
+    public AbstractInternalAdminServer(AdminServerSetting adminServerSetting) {
+        this.adminServerSetting = adminServerSetting;
+        this.adminServerConfig = adminServerSetting.getAdminServerConfig();
+        this.backendConfig = adminServerSetting.getBackendConfig();
+    }
+
+    @Override
+    public AdminServerSetting getSetting() {
+        return adminServerSetting;
+    }
+
+    public boolean isStarted() {
+        return started;
+    }
+
+    protected String getServiceName() {
+        return adminServerConfig.getAdminServiceName();
+    }
+
+    protected IdentityService getIdentityService() {
+        if (identityService == null) {
+            if (backend instanceof MemoryIdentityBackend) { // Already in memory
+                identityService = backend;
+            } else {
+                identityService = new CacheableIdentityService(
+                        backendConfig, backend);
+            }
+        }
+        return identityService;
+    }
+
+    @Override
+    public void init() throws KrbException {
+        backend = KdcUtil.getBackend(backendConfig);
+    }
+
+    @Override
+    public void start() throws KrbException {
+        try {
+            doStart();
+        } catch (Exception e) {
+            throw new KrbException("Failed to start " + getServiceName(), e);
+        }
+
+        started = true;
+    }
+
+    public boolean enableDebug() {
+        return adminServerConfig.enableDebug();
+    }
+
+    @Override
+    public IdentityBackend getIdentityBackend() {
+        return backend;
+    }
+
+    protected void doStart() throws Exception {
+        backend.start();
+    }
+
+    public void stop() throws KrbException {
+        try {
+            doStop();
+        } catch (Exception e) {
+            throw new KrbException("Failed to stop " + getServiceName(), e);
+        }
+
+        started = false;
+    }
+
+    protected void doStop() throws Exception {
+        backend.stop();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/DefaultAdminServerHandler.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/DefaultAdminServerHandler.java b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/DefaultAdminServerHandler.java
new file mode 100644
index 0000000..1dbb017
--- /dev/null
+++ b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/DefaultAdminServerHandler.java
@@ -0,0 +1,199 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.apache.kerby.kerberos.kerb.admin.server.kadmin.impl;
+
+import org.apache.kerby.kerberos.kerb.admin.AuthUtil;
+import org.apache.kerby.kerberos.kerb.admin.server.kadmin.AdminServerContext;
+import org.apache.kerby.kerberos.kerb.admin.server.kadmin.AdminServerHandler;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.sasl.AuthorizeCallback;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslServer;
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.SocketTimeoutException;
+import java.nio.ByteBuffer;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Map;
+
+public class DefaultAdminServerHandler extends AdminServerHandler implements Runnable {
+    private static Logger logger = LoggerFactory.getLogger(DefaultAdminServerHandler.class);
+    private final KrbTransport transport;
+    private static boolean sasl = false;
+    private AdminServerContext adminServerContext;
+
+    public DefaultAdminServerHandler(AdminServerContext adminServerContext, KrbTransport transport) {
+        super(adminServerContext);
+        this.transport  = transport;
+        this.adminServerContext = adminServerContext;
+    }
+
+    @Override
+    public void run() {
+        while (true) {
+            try {
+                if (!sasl) {
+                    logger.info("Doing the sasl negotiation !!!");
+                    try {
+                        saslNegotiation();
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                } else {
+                    ByteBuffer message = transport.receiveMessage();
+                    if (message == null) {
+                        logger.debug("No valid request recved. Disconnect actively");
+                        transport.release();
+                        break;
+                    }
+                    handleMessage(message);
+                }
+            } catch (IOException e) {
+                transport.release();
+                logger.debug("Transport or decoding error occurred, "
+                        + "disconnecting abnormally", e);
+                break;
+            }
+        }
+    }
+
+    protected void handleMessage(ByteBuffer message) {
+        InetAddress clientAddress = transport.getRemoteAddress();
+
+        try {
+            ByteBuffer adminResponse = handleMessage(message, clientAddress);
+            transport.sendMessage(adminResponse);
+        } catch (Exception e) {
+            transport.release();
+            logger.error("Error occured while processing request:", e);
+        }
+    }
+
+    private void saslNegotiation() throws Exception {
+
+        File keytabFile = new File(adminServerContext.getConfig().getKeyTabFile());
+        String principal = adminServerContext.getConfig().getProtocol() + "/"
+            + adminServerContext.getConfig().getAdminHost();
+
+        Subject subject = AuthUtil.loginUsingKeytab(principal, keytabFile);
+        Subject.doAs(subject, new PrivilegedAction<Object>() {
+            @Override
+            public Object run() {
+                try {
+                    ByteBuffer message = null;
+                    try {
+                        message = transport.receiveMessage();
+                    } catch (SocketTimeoutException e) {
+                        // ignore time out
+                        return null;
+                    }
+
+                    Map<String, Object> props = new HashMap<String, Object>();
+                    props.put(Sasl.QOP, "auth-conf");
+                    props.put(Sasl.SERVER_AUTH, "true");
+
+                    String protocol = adminServerContext.getConfig().getProtocol();
+                    String serverName = adminServerContext.getConfig().getServerName();
+                    CallbackHandler callbackHandler = new SaslGssCallbackHandler();
+                    SaslServer ss = Sasl.createSaslServer("GSSAPI",
+                        protocol, serverName, props, callbackHandler);
+
+                    if (ss == null) {
+                        throw new Exception("Unable to find server implementation for: GSSAPI");
+                    }
+
+                    while (!ss.isComplete()) {
+                        int scComplete = message.getInt();
+                        if (scComplete == 0) {
+                            System.out.println("success!!!");
+                            sasl = true;
+                            break;
+                        }
+                        sendMessage(message, ss);
+                        if (!ss.isComplete()) {
+                            logger.info("Waiting receive message");
+                            message = transport.receiveMessage();
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                return null;
+            }
+        });
+
+    }
+
+    private void sendMessage(ByteBuffer message, SaslServer ss) throws IOException {
+
+        byte[] arr = new byte[message.remaining()];
+        message.get(arr);
+        byte[] challenge = ss.evaluateResponse(arr);
+
+        // 4 is the head to go through network
+        ByteBuffer buffer = ByteBuffer.allocate(challenge.length + 8);
+        buffer.putInt(challenge.length + 4);
+        int ssComplete = ss.isComplete() ? 0 : 1;
+        buffer.putInt(ssComplete);
+        buffer.put(challenge);
+        buffer.flip();
+        transport.sendMessage(buffer);
+    }
+
+    private static class SaslGssCallbackHandler implements CallbackHandler {
+
+        @Override
+        public void handle(Callback[] callbacks) throws
+            UnsupportedCallbackException {
+            AuthorizeCallback ac = null;
+            for (Callback callback : callbacks) {
+                if (callback instanceof AuthorizeCallback) {
+                    ac = (AuthorizeCallback) callback;
+                } else {
+                    throw new UnsupportedCallbackException(callback,
+                        "Unrecognized SASL GSSAPI Callback");
+                }
+            }
+            if (ac != null) {
+                String authid = ac.getAuthenticationID();
+                String authzid = ac.getAuthorizationID();
+                if (authid.equals(authzid)) {
+                    ac.setAuthorized(true);
+                } else {
+                    ac.setAuthorized(false);
+                }
+                if (ac.isAuthorized()) {
+                    // System.out.println("SASL server GSSAPI callback: setting "
+                    //+ "canonicalized client ID: " + authzid);
+                    ac.setAuthorizedID(authzid);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/DefaultInternalAdminServerImpl.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/DefaultInternalAdminServerImpl.java b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/DefaultInternalAdminServerImpl.java
new file mode 100644
index 0000000..4234481
--- /dev/null
+++ b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/DefaultInternalAdminServerImpl.java
@@ -0,0 +1,80 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *
+ */
+package org.apache.kerby.kerberos.kerb.admin.server.kadmin.impl;
+
+import org.apache.kerby.kerberos.kerb.admin.server.kadmin.AdminServerContext;
+import org.apache.kerby.kerberos.kerb.admin.server.kadmin.AdminServerSetting;
+import org.apache.kerby.kerberos.kerb.admin.server.kadmin.AdminServerUtil;
+import org.apache.kerby.kerberos.kerb.transport.KdcNetwork;
+import org.apache.kerby.kerberos.kerb.transport.KrbTransport;
+import org.apache.kerby.kerberos.kerb.transport.TransportPair;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * A default admin admin implementation.
+ */
+public class DefaultInternalAdminServerImpl extends AbstractInternalAdminServer {
+    private ExecutorService executor;
+    private AdminServerContext adminContext;
+    private KdcNetwork network;
+
+    public DefaultInternalAdminServerImpl(AdminServerSetting adminSetting) {
+        super(adminSetting);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        prepareHandler();
+
+        executor = Executors.newCachedThreadPool();
+
+        network = new KdcNetwork() {
+            @Override
+            protected void onNewTransport(KrbTransport transport) {
+                DefaultAdminServerHandler kdcHandler = 
+                    new DefaultAdminServerHandler(adminContext, transport);
+                executor.execute(kdcHandler);
+            }
+        };
+
+        network.init();
+        TransportPair tpair = AdminServerUtil.getTransportPair(getSetting());
+        network.listen(tpair);
+        network.start();
+    }
+
+    private void prepareHandler() {
+        adminContext = new AdminServerContext(getSetting());
+        adminContext.setIdentityService(getIdentityService());
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+
+        network.stop();
+
+        executor.shutdownNow();
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/InternalAdminServer.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/InternalAdminServer.java b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/InternalAdminServer.java
new file mode 100644
index 0000000..c0cde44
--- /dev/null
+++ b/kerby-kerb/kerb-admin-server/src/main/java/org/apache/kerby/kerberos/kerb/admin/server/kadmin/impl/InternalAdminServer.java
@@ -0,0 +1,60 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *
+ */
+package org.apache.kerby.kerberos.kerb.admin.server.kadmin.impl;
+
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.admin.server.kadmin.AdminServerSetting;
+import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
+
+/**
+ * An internal KDC admin interface.
+ */
+public interface InternalAdminServer {
+
+    /**
+     * Initialize.
+     * @throws KrbException e
+     */
+    void init() throws KrbException;
+
+    /**
+     * Start the KDC admin.
+     * @throws KrbException e
+     */
+    void start() throws KrbException;
+
+    /**
+     * Stop the KDC admin.
+     * @throws KrbException e
+     */
+    void stop() throws KrbException;
+
+    /**
+     * Get admin admin setting.
+     * @return setting
+     */
+    AdminServerSetting getSetting();
+
+    /**
+     * Get identity backend.
+     * @return IdentityBackend
+     */
+    IdentityBackend getIdentityBackend();
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin-server/src/main/resources/adminServer.conf
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin-server/src/main/resources/adminServer.conf b/kerby-kerb/kerb-admin-server/src/main/resources/adminServer.conf
new file mode 100644
index 0000000..8c7a11e
--- /dev/null
+++ b/kerby-kerb/kerb-admin-server/src/main/resources/adminServer.conf
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+[libdefaults]
+default_realm = TEST.COM
+admin_port = 65417
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin/pom.xml
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/pom.xml b/kerby-kerb/kerb-admin/pom.xml
index 2a50bce..e4d52de 100644
--- a/kerby-kerb/kerb-admin/pom.xml
+++ b/kerby-kerb/kerb-admin/pom.xml
@@ -37,5 +37,10 @@
       <artifactId>kerb-util</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.kerby</groupId>
+      <artifactId>kerby-xdr</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/AdminHelper.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/AdminHelper.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/AdminHelper.java
deleted file mode 100644
index 62c38b6..0000000
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/AdminHelper.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *  
- *    http://www.apache.org/licenses/LICENSE-2.0
- *  
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *  
- */
-package org.apache.kerby.kerberos.kerb.admin;
-
-import org.apache.kerby.KOptions;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
-import org.apache.kerby.kerberos.kerb.keytab.Keytab;
-import org.apache.kerby.kerberos.kerb.keytab.KeytabEntry;
-import org.apache.kerby.kerberos.kerb.type.KerberosTime;
-import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
-import org.apache.kerby.kerberos.kerb.type.base.EncryptionType;
-import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * LocalKadmin utilities.
- */
-public final class AdminHelper {
-
-    private AdminHelper() { }
-
-    /**
-     * Export all the keys of the specified principal into the specified keytab
-     * file.
-     *
-     * @param keytabFile The keytab file
-     * @param identity  The identity
-     * @throws KrbException
-     */
-    static void exportKeytab(File keytabFile, KrbIdentity identity)
-            throws KrbException {
-
-        Keytab keytab = createOrLoadKeytab(keytabFile);
-
-        exportToKeytab(keytab, identity);
-
-        storeKeytab(keytab, keytabFile);
-    }
-
-    /**
-     * Export all the keys of the specified principal into the specified keytab
-     * file.
-     *
-     * @param keytabFile The keytab file
-     * @param identities  Identities to export to keytabFile
-     * @throws KrbException
-     */
-    static void exportKeytab(File keytabFile, List<KrbIdentity> identities)
-            throws KrbException {
-
-        Keytab keytab = createOrLoadKeytab(keytabFile);
-
-        for (KrbIdentity identity : identities) {
-            exportToKeytab(keytab, identity);
-        }
-
-        storeKeytab(keytab, keytabFile);
-    }
-
-    /**
-     * Load keytab from keytab file.
-     *
-     * @param keytabFile The keytab file
-     * @return The keytab load from keytab file
-     * @throws KrbException
-     */
-    static Keytab loadKeytab(File keytabFile) throws KrbException {
-        Keytab keytab;
-        try {
-            keytab = Keytab.loadKeytab(keytabFile);
-        } catch (IOException e) {
-            throw new KrbException("Failed to load keytab", e);
-        }
-
-        return keytab;
-    }
-
-    /**
-     * If keytab file does not exist, create a new keytab,
-     * otherwise load keytab from keytab file.
-     *
-     * @param keytabFile The keytab file
-     * @return The keytab load from keytab file
-     * @throws KrbException
-     */
-    static Keytab createOrLoadKeytab(File keytabFile) throws KrbException {
-
-        Keytab keytab;
-        try {
-            if (!keytabFile.exists()) {
-                if (!keytabFile.createNewFile()) {
-                    throw new KrbException("Failed to create keytab file "
-                            + keytabFile.getAbsolutePath());
-                }
-                keytab = new Keytab();
-            } else {
-                keytab = Keytab.loadKeytab(keytabFile);
-            }
-        } catch (IOException e) {
-            throw new KrbException("Failed to load or create keytab", e);
-        }
-
-        return keytab;
-    }
-
-    /**
-     * Export all the keys of the specified identity into the keytab.
-     *
-     * @param keytab The keytab
-     * @param identity  The identity
-     * @throws KrbException
-     */
-    static void exportToKeytab(Keytab keytab, KrbIdentity identity)
-        throws KrbException {
-
-        //Add principal to keytab.
-        PrincipalName principal = identity.getPrincipal();
-        KerberosTime timestamp = KerberosTime.now();
-        for (EncryptionType encType : identity.getKeys().keySet()) {
-            EncryptionKey ekey = identity.getKeys().get(encType);
-            int keyVersion = ekey.getKvno();
-            keytab.addEntry(new KeytabEntry(principal, timestamp, keyVersion, ekey));
-        }
-    }
-
-    /**
-     * Store the keytab to keytab file.
-     *
-     * @param keytab   The keytab
-     * @param keytabFile The keytab file
-     * @throws KrbException
-     */
-    static void storeKeytab(Keytab keytab, File keytabFile) throws KrbException {
-        try {
-            keytab.store(keytabFile);
-        } catch (IOException e) {
-            throw new KrbException("Failed to store keytab", e);
-        }
-    }
-
-    /**
-     * Remove all the keys of the specified principal in the specified keytab
-     * file.
-     *
-     * @param keytabFile The keytab file
-     * @param principalName  The principal name
-     * @throws KrbException
-     */
-    static void removeKeytabEntriesOf(File keytabFile,
-                                             String principalName) throws KrbException {
-        Keytab keytab = loadKeytab(keytabFile);
-
-        keytab.removeKeytabEntries(new PrincipalName(principalName));
-
-        storeKeytab(keytab, keytabFile);
-    }
-
-    /**
-     * Remove all the keys of the specified principal with specified kvno
-     * in the specified keytab file.
-     *
-     * @param keytabFile The keytab file
-     * @param principalName  The principal name
-     * @param kvno The kvno
-     * @throws KrbException
-     */
-    static void removeKeytabEntriesOf(File keytabFile,
-                                      String principalName, int kvno) throws KrbException {
-        Keytab keytab = loadKeytab(keytabFile);
-
-        keytab.removeKeytabEntries(new PrincipalName(principalName), kvno);
-
-        storeKeytab(keytab, keytabFile);
-    }
-
-    /**
-     * Remove all the old keys of the specified principal
-     * in the specified keytab file.
-     *
-     * @param keytabFile The keytab file
-     * @param principalName  The principal name
-     * @throws KrbException
-     */
-    static void removeOldKeytabEntriesOf(File keytabFile,
-                                                String principalName) throws KrbException {
-        Keytab keytab = loadKeytab(keytabFile);
-
-        List<KeytabEntry> entries = keytab.getKeytabEntries(
-                new PrincipalName(principalName));
-
-        int maxKvno = 0;
-        for (KeytabEntry entry : entries) {
-            if (maxKvno < entry.getKvno()) {
-                maxKvno = entry.getKvno();
-            }
-        }
-
-        for (KeytabEntry entry : entries) {
-            if (entry.getKvno() < maxKvno) {
-                keytab.removeKeytabEntry(entry);
-            }
-        }
-
-        storeKeytab(keytab, keytabFile);
-    }
-
-    /**
-     * Create principal.
-     *
-     * @param principal The principal name to be created
-     * @param kOptions  The KOptions with principal info
-     */
-    static KrbIdentity createIdentity(String principal, 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(new KerberosTime(253402300799900L));
-        }
-        if (kOptions.contains(KadminOption.KVNO)) {
-            kid.setKeyVersion(kOptions.getIntegerOption(KadminOption.KVNO));
-        } else {
-            kid.setKeyVersion(1);
-        }
-        kid.setDisabled(false);
-        kid.setLocked(false);
-
-        return kid;
-    }
-
-    /**
-     * Modify the principal with KOptions.
-     *
-     * @param identity The identity to be modified
-     * @param kOptions  The KOptions with changed principal info
-     * @throws KrbException
-     */
-    static void updateIdentity(KrbIdentity identity, KOptions kOptions) {
-        if (kOptions.contains(KadminOption.EXPIRE)) {
-            Date date = kOptions.getDateOption(KadminOption.EXPIRE);
-            identity.setExpireTime(new KerberosTime(date.getTime()));
-        }
-        if (kOptions.contains(KadminOption.DISABLED)) {
-            identity.setDisabled(kOptions.getBooleanOption(KadminOption.DISABLED, false));
-        }
-        if (kOptions.contains(KadminOption.LOCKED)) {
-            identity.setLocked(kOptions.getBooleanOption(KadminOption.LOCKED, false));
-        }
-    }
-
-    /**
-     * Get all the Pattern for matching from glob string.
-     * The glob string can contain "." "*" and "[]"
-     *
-     * @param globString The glob string for matching
-     * @return pattern
-     * @throws KrbException
-     */
-    static Pattern getPatternFromGlobPatternString(String globString) throws KrbException {
-        if (globString == null || globString.equals("")) {
-            return null;
-        }
-        if (!Pattern.matches("^[0-9A-Za-z._/@*?\\[\\]\\-]+$", globString)) {
-            throw new KrbException("Glob pattern string contains invalid character");
-        }
-
-        String patternString = globString;
-        patternString = patternString.replaceAll("\\.", "\\\\.");
-        patternString = patternString.replaceAll("\\?", ".");
-        patternString = patternString.replaceAll("\\*", ".*");
-        patternString = "^" + patternString + "$";
-
-        Pattern pt;
-        try {
-            pt = Pattern.compile(patternString);
-        } catch (PatternSyntaxException e) {
-            throw new KrbException("Invalid glob pattern string");
-        }
-        return pt;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/AuthUtil.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/AuthUtil.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/AuthUtil.java
new file mode 100644
index 0000000..68d03e7
--- /dev/null
+++ b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/AuthUtil.java
@@ -0,0 +1,141 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.kerberos.kerb.admin;
+
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosPrincipal;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import java.io.File;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class AuthUtil {
+
+    public static final boolean ENABLE_DEBUG = true;
+
+    private static String getKrb5LoginModuleName() {
+        return System.getProperty("java.vendor").contains("IBM")
+            ? "com.ibm.security.auth.module.Krb5LoginModule"
+            : "com.sun.security.auth.module.Krb5LoginModule";
+    }
+
+    public static Subject loginUsingTicketCache(
+        String principal, File cacheFile) throws LoginException {
+        Set<Principal> principals = new HashSet<Principal>();
+        principals.add(new KerberosPrincipal(principal));
+
+        Subject subject = new Subject(false, principals,
+            new HashSet<Object>(), new HashSet<Object>());
+
+        Configuration conf = useTicketCache(principal, cacheFile);
+        String confName = "TicketCacheConf";
+        LoginContext loginContext = new LoginContext(confName, subject, null, conf);
+        loginContext.login();
+        return loginContext.getSubject();
+    }
+
+    public static Subject loginUsingKeytab(
+        String principal, File keytabFile) throws LoginException {
+        Set<Principal> principals = new HashSet<Principal>();
+        principals.add(new KerberosPrincipal(principal));
+
+        Subject subject = new Subject(false, principals,
+            new HashSet<Object>(), new HashSet<Object>());
+
+        Configuration conf = useKeytab(principal, keytabFile);
+        String confName = "KeytabConf";
+        LoginContext loginContext = new LoginContext(confName, subject, null, conf);
+        loginContext.login();
+        return loginContext.getSubject();
+    }
+
+    public static Configuration useTicketCache(String principal,
+                                               File credentialFile) {
+        return new TicketCacheJaasConf(principal, credentialFile);
+    }
+
+    public static Configuration useKeytab(String principal, File keytabFile) {
+        return new KeytabJaasConf(principal, keytabFile);
+    }
+
+    static class TicketCacheJaasConf extends Configuration {
+        private String principal;
+        private File clientCredentialFile;
+
+        TicketCacheJaasConf(String principal, File clientCredentialFile) {
+            this.principal = principal;
+            this.clientCredentialFile = clientCredentialFile;
+        }
+
+        @Override
+        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+            Map<String, String> options = new HashMap<String, String>();
+            options.put("principal", principal);
+            options.put("storeKey", "false");
+            options.put("doNotPrompt", "false");
+            options.put("useTicketCache", "true");
+            options.put("renewTGT", "true");
+            options.put("refreshKrb5Config", "true");
+            options.put("isInitiator", "true");
+            options.put("ticketCache", clientCredentialFile.getAbsolutePath());
+            options.put("debug", String.valueOf(ENABLE_DEBUG));
+
+            return new AppConfigurationEntry[]{
+                new AppConfigurationEntry(getKrb5LoginModuleName(),
+                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                    options)};
+        }
+    }
+
+    static class KeytabJaasConf extends Configuration {
+        private String principal;
+        private File keytabFile;
+
+        KeytabJaasConf(String principal, File keytab) {
+            this.principal = principal;
+            this.keytabFile = keytab;
+        }
+
+        @Override
+        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+            Map<String, String> options = new HashMap<String, String>();
+            options.put("keyTab", keytabFile.getAbsolutePath());
+            options.put("principal", principal);
+            options.put("useKeyTab", "true");
+            options.put("storeKey", "true");
+            options.put("doNotPrompt", "true");
+            options.put("renewTGT", "false");
+            options.put("refreshKrb5Config", "true");
+            options.put("isInitiator", "true");
+            options.put("debug", String.valueOf(ENABLE_DEBUG));
+
+            return new AppConfigurationEntry[]{
+                new AppConfigurationEntry(getKrb5LoginModuleName(),
+                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED,
+                    options)};
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Kadmin.java
----------------------------------------------------------------------
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
deleted file mode 100644
index 594ff6b..0000000
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Kadmin.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *
- */
-package org.apache.kerby.kerberos.kerb.admin;
-
-import org.apache.kerby.KOptions;
-import org.apache.kerby.kerberos.kerb.KrbException;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * Server side admin facilities from remote, similar to MIT kadmin remote mode.
- */
-public interface Kadmin {
-
-    /**
-     * Get the kadmin principal name.
-     *
-     * @return The kadmin principal name.
-     */
-    String getKadminPrincipal();
-
-    /**
-     * Add principal to backend.
-     *
-     * @param principal The principal to be added into backend
-     * @throws KrbException e
-     */
-    void addPrincipal(String principal) throws KrbException;
-
-    /**
-     * Add principal to backend.
-     *
-     * @param principal The principal to be added into backend
-     * @param kOptions The KOptions with principal info
-     * @throws KrbException e
-     */
-    void addPrincipal(String principal, KOptions kOptions) throws KrbException;
-
-    /**
-     * Add principal to backend.
-     *
-     * @param principal The principal to be added into backend
-     * @param password  The password to create encryption key
-     * @throws KrbException e
-     */
-    void addPrincipal(String principal, String password) throws KrbException;
-
-    /**
-     * Add principal to backend.
-     *
-     * @param principal The principal to be added into backend
-     * @param password  The password to create encryption key
-     * @param kOptions  The KOptions with principal info
-     * @throws KrbException e
-     */
-    void addPrincipal(String principal, String password,
-                      KOptions kOptions) throws KrbException;
-
-    /**
-     * Export all the keys of the specified principal into the specified keytab
-     * file.
-     *
-     * @param keytabFile The keytab file
-     * @param principal The principal name
-     * @throws KrbException e
-     */
-    void exportKeytab(File keytabFile, String principal) throws KrbException;
-
-    /**
-     * Export all the keys of the specified principals into the specified keytab
-     * file.
-     *
-     * @param keytabFile The keytab file
-     * @param principals The principal names
-     * @throws KrbException e
-     */
-    void exportKeytab(File keytabFile,
-                      List<String> principals) throws KrbException;
-
-    /**
-     * Export all identity keys to the specified keytab file.
-     *
-     * @param keytabFile The keytab file
-     * @throws KrbException e
-     */
-    void exportKeytab(File keytabFile) throws KrbException;
-
-    /**
-     * Remove all the keys of the specified principal in the specified keytab
-     * file.
-     *
-     * @param keytabFile The keytab file
-     * @param principal The principal name
-     * @throws KrbException e
-     */
-    void removeKeytabEntriesOf(File keytabFile, String principal)
-            throws KrbException;
-
-    /**
-     * Remove all the keys of the specified principal with specified kvno
-     * in the specified keytab file.
-     *
-     * @param keytabFile The keytab file
-     * @param principal The principal name
-     * @param kvno The kvno
-     * @throws KrbException e
-     */
-    void removeKeytabEntriesOf(File keytabFile, String principal, int kvno)
-            throws KrbException;
-
-    /**
-     * Remove all the old keys of the specified principal
-     * in the specified keytab file.
-     *
-     * @param keytabFile The keytab file
-     * @param principal The principal name
-     * @throws KrbException e
-     */
-    void removeOldKeytabEntriesOf(File keytabFile, String principal)
-            throws KrbException;
-
-    /**
-     * Delete the principal in backend.
-     *
-     * @param principal The principal to be deleted from backend
-     * @throws KrbException e
-     */
-    void deletePrincipal(String principal) throws KrbException;
-
-    /**
-     * Modify the principal with KOptions.
-     *
-     * @param principal The principal to be modified
-     * @param kOptions The KOptions with changed principal info
-     * @throws KrbException e
-     */
-    void modifyPrincipal(String principal, KOptions kOptions) throws KrbException;
-
-    /**
-     * Rename the principal.
-     *
-     * @param oldPrincipalName The original principal name
-     * @param newPrincipalName The new principal name
-     * @throws KrbException e
-     */
-    void renamePrincipal(String oldPrincipalName,
-                         String newPrincipalName) throws KrbException;
-
-    /**
-     * Get all the principal names from backend.
-     *
-     * @return principal list
-     * @throws KrbException e
-     */
-    List<String> getPrincipals() throws KrbException;
-
-    /**
-     * Get all the principal names that meets the pattern
-     *
-     * @param globString The glob string for matching
-     * @return Principal names
-     * @throws KrbException e
-     */
-    List<String> getPrincipals(String globString) throws KrbException;
-
-    /**
-     * Change the password of specified principal.
-     *
-     * @param principal The principal to be updated password
-     * @param newPassword The new password
-     * @throws KrbException e
-     */
-    void changePassword(String principal, String newPassword) throws KrbException;
-
-    /**
-     * Update the random keys of specified principal.
-     *
-     * @param principal The principal to be updated keys
-     * @throws KrbException e
-     */
-    void updateKeys(String principal) throws KrbException;
-
-    /**
-     * Release any resources associated.
-     *
-     * @throws KrbException e
-     */
-    void release() throws KrbException;
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
deleted file mode 100644
index 0c11fe7..0000000
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- *
- */
-package org.apache.kerby.kerberos.kerb.admin;
-
-import org.apache.kerby.KOption;
-import org.apache.kerby.KOptionInfo;
-import org.apache.kerby.KOptionType;
-
-public enum KadminOption implements KOption {
-    NONE(null),
-    EXPIRE(new KOptionInfo("-expire", "expire time", KOptionType.DATE)),
-    DISABLED(new KOptionInfo("-disabled", "disabled", KOptionType.BOOL)),
-    LOCKED(new KOptionInfo("-locked", "locked", KOptionType.BOOL)),
-    FORCE(new KOptionInfo("-force", "force", KOptionType.NOV)),
-    KVNO(new KOptionInfo("-kvno", "initial key version number", KOptionType.INT)),
-    SIZE(new KOptionInfo("-size", "principal's numbers", KOptionType.STR)),
-    PW(new KOptionInfo("-pw", "password", KOptionType.STR)),
-    RANDKEY(new KOptionInfo("-randkey", "random key", KOptionType.NOV)),
-    KEEPOLD(new KOptionInfo("-keepold", "keep old passowrd", KOptionType.NOV)),
-    KEYSALTLIST(new KOptionInfo("-e", "key saltlist", KOptionType.STR)),
-    K(new KOptionInfo("-k", "keytab file path", KOptionType.STR)),
-    KEYTAB(new KOptionInfo("-keytab", "keytab file path", KOptionType.STR)),
-    CCACHE(new KOptionInfo("-c", "credentials cache", KOptionType.FILE));
-
-    private final KOptionInfo optionInfo;
-
-    KadminOption(KOptionInfo optionInfo) {
-        this.optionInfo = optionInfo;
-    }
-
-    @Override
-    public KOptionInfo getOptionInfo() {
-        return optionInfo;
-    }
-
-    public static KadminOption fromName(String name) {
-        if (name != null) {
-            for (KadminOption ko : values()) {
-                if (ko.optionInfo != null
-                        && ko.optionInfo.getName().equals(name)) {
-                    return ko;
-                }
-            }
-        }
-        return NONE;
-    }
-
-    public static KadminOption fromOptionName(String optionName) {
-        if (optionName != null) {
-            for (KadminOption ko : values()) {
-                if (ko.optionInfo != null
-                    && ko.optionInfo.getName().equals(optionName)) {
-                    return ko;
-                }
-            }
-        }
-        return NONE;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminServer.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminServer.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminServer.java
deleted file mode 100644
index 933accf..0000000
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminServer.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *
- */
-package org.apache.kerby.kerberos.kerb.admin;
-
-import org.apache.kerby.KOptions;
-import org.apache.kerby.kerberos.kerb.KrbException;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * Server side admin facilities for remote, similar to MIT kadmind service.
- * It uses GSSAPI and XDR to communicate with remote client/kadmin to receive
- * and perform the requested operations. In this server side, it simply leverages
- * LocalKadmin to perform the real work.
- *
- * TO BE IMPLEMENTED.
- */
-public class KadminServer implements Kadmin {
-    //private LocalKadmin localKadmin;
-
-    @Override
-    public String getKadminPrincipal() {
-        return null;
-    }
-
-    @Override
-    public void addPrincipal(String principal) throws KrbException {
-
-    }
-
-    @Override
-    public void addPrincipal(String principal,
-                             KOptions kOptions) throws KrbException {
-
-    }
-
-    @Override
-    public void addPrincipal(String principal,
-                             String password) throws KrbException {
-
-    }
-
-    @Override
-    public void addPrincipal(String principal, String password,
-                             KOptions kOptions) throws KrbException {
-
-    }
-
-    @Override
-    public void exportKeytab(File keytabFile,
-                             String principal) throws KrbException {
-
-    }
-
-    @Override
-    public void exportKeytab(File keytabFile,
-                             List<String> principals) throws KrbException {
-
-    }
-
-    @Override
-    public void exportKeytab(File keytabFile) throws KrbException {
-
-    }
-
-    @Override
-    public void removeKeytabEntriesOf(File keytabFile,
-                                      String principal) throws KrbException {
-
-    }
-
-    @Override
-    public void removeKeytabEntriesOf(File keytabFile, String principal,
-                                      int kvno) throws KrbException {
-
-    }
-
-    @Override
-    public void removeOldKeytabEntriesOf(File keytabFile,
-                                         String principal) throws KrbException {
-
-    }
-
-    @Override
-    public void deletePrincipal(String principal) throws KrbException {
-
-    }
-
-    @Override
-    public void modifyPrincipal(String principal,
-                                KOptions kOptions) throws KrbException {
-
-    }
-
-    @Override
-    public void renamePrincipal(String oldPrincipalName,
-                                String newPrincipalName) throws KrbException {
-
-    }
-
-    @Override
-    public List<String> getPrincipals() throws KrbException {
-        return null;
-    }
-
-    @Override
-    public List<String> getPrincipals(String globString) throws KrbException {
-        return null;
-    }
-
-    @Override
-    public void changePassword(String principal,
-                               String newPassword) throws KrbException {
-
-    }
-
-    @Override
-    public void updateKeys(String principal) throws KrbException {
-
-    }
-
-    @Override
-    public void release() throws KrbException {
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Krb5Conf.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Krb5Conf.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Krb5Conf.java
new file mode 100644
index 0000000..9e3b3cf
--- /dev/null
+++ b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/Krb5Conf.java
@@ -0,0 +1,86 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+package org.apache.kerby.kerberos.kerb.admin;
+
+import org.apache.kerby.kerberos.kerb.server.KdcConfig;
+import org.apache.kerby.util.IOUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Generate krb5 file using given kdc server settings.
+ */
+public class Krb5Conf {
+    public static final String KRB5_CONF = "java.security.krb5.conf";
+    private static final String KRB5_CONF_FILE = "krb5.conf";
+    private File confDir;
+    private KdcConfig kdcConfig;
+
+    public Krb5Conf(File confDir, KdcConfig kdcConfig) {
+        this.confDir = confDir;
+        this.kdcConfig = kdcConfig;
+    }
+
+    public void initKrb5conf() throws IOException {
+        File confFile = generateConfFile();
+        System.setProperty(KRB5_CONF, confFile.getAbsolutePath());
+    }
+
+    // Read in krb5.conf and substitute in the correct port
+    private File generateConfFile() throws IOException {
+
+        String resourcePath = kdcConfig.allowUdp() ? "/krb5_udp.conf" : "/krb5.conf";
+        InputStream templateResource = getClass().getResourceAsStream(resourcePath);
+
+        String templateContent = IOUtil.readInput(templateResource);
+
+        String content = templateContent;
+
+        content = content.replaceAll("_REALM_", "" + kdcConfig.getKdcRealm());
+
+        int kdcPort = kdcConfig.allowUdp() ? kdcConfig.getKdcUdpPort()
+                : kdcConfig.getKdcTcpPort();
+        content = content.replaceAll("_KDC_PORT_",
+                String.valueOf(kdcPort));
+
+        if (kdcConfig.allowTcp()) {
+            content = content.replaceAll("#_KDC_TCP_PORT_", "kdc_tcp_port = " + kdcConfig.getKdcTcpPort());
+        }
+        if (kdcConfig.allowUdp()) {
+            content = content.replaceAll("#_KDC_UDP_PORT_", "kdc_udp_port = " + kdcConfig.getKdcUdpPort());
+        }
+
+        int udpLimit = kdcConfig.allowUdp() ? 4096 : 1;
+        content = content.replaceAll("_UDP_LIMIT_", String.valueOf(udpLimit));
+
+        File confFile = new File(confDir, KRB5_CONF_FILE);
+        if (confFile.exists()) {
+            boolean delete = confFile.delete();
+            if (!delete) {
+                throw new RuntimeException("File delete error!");
+            }
+        }
+        IOUtil.writeFile(content, confFile);
+
+        return confFile;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadmin.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadmin.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadmin.java
deleted file mode 100644
index d8d38f1..0000000
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadmin.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *
- */
-package org.apache.kerby.kerberos.kerb.admin;
-
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
-import org.apache.kerby.kerberos.kerb.identity.backend.BackendConfig;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
-import org.apache.kerby.kerberos.kerb.server.KdcConfig;
-
-/**
- * Server side admin facilities for local, similar to MIT kadmin local mode. It
- * may be not accurate regarding 'local' because, if the identity backend itself
- * is supported to be accessed from remote, it won't have to be remote; but if
- * not, then it must be local to the KDC server bounded with the local backend.
- *
- * Note, suitable with Kerby KdcServer based KDCs like Kerby KDC.
- */
-public interface LocalKadmin extends Kadmin {
-
-    /**
-     * Check the built-in principals, will throw KrbException if not exist.
-     * @throws KrbException e
-     */
-    void checkBuiltinPrincipals() throws KrbException;
-
-    /**
-     * Create build-in principals.
-     * @throws KrbException e
-     */
-    void createBuiltinPrincipals() throws KrbException;
-
-    /**
-     * Delete build-in principals.
-     * @throws KrbException e
-     */
-    void deleteBuiltinPrincipals() throws KrbException;
-
-    /**
-     * Get kdc config.
-     *
-     * @return The kdc config.
-     */
-    KdcConfig getKdcConfig();
-
-    /**
-     * Get backend config.
-     *
-     * @return The backend config.
-     */
-    BackendConfig getBackendConfig();
-
-    /**
-     * Get identity backend.
-     *
-     * @return IdentityBackend
-     */
-    IdentityBackend getIdentityBackend();
-
-    /**
-     * Get the identity from backend.
-     *
-     * @param principalName The principal name
-     * @return identity
-     * @throws KrbException e
-     */
-    KrbIdentity getPrincipal(String principalName) throws KrbException;
-
-    int size() throws KrbException;
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/9f628e5a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadminImpl.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadminImpl.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadminImpl.java
deleted file mode 100644
index 9f0f89e..0000000
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadminImpl.java
+++ /dev/null
@@ -1,400 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License. 
- *
- */
-package org.apache.kerby.kerberos.kerb.admin;
-
-import org.apache.kerby.KOptions;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.common.EncryptionUtil;
-import org.apache.kerby.kerberos.kerb.common.KrbUtil;
-import org.apache.kerby.kerberos.kerb.identity.KrbIdentity;
-import org.apache.kerby.kerberos.kerb.identity.backend.BackendConfig;
-import org.apache.kerby.kerberos.kerb.identity.backend.IdentityBackend;
-import org.apache.kerby.kerberos.kerb.keytab.Keytab;
-import org.apache.kerby.kerberos.kerb.server.KdcConfig;
-import org.apache.kerby.kerberos.kerb.server.KdcSetting;
-import org.apache.kerby.kerberos.kerb.server.KdcUtil;
-import org.apache.kerby.kerberos.kerb.type.base.EncryptionKey;
-import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The implementation of server side admin facilities for local mode.
- */
-public class LocalKadminImpl implements LocalKadmin {
-    private static final Logger LOG = LoggerFactory.getLogger(LocalKadminImpl.class);
-
-    private final KdcSetting kdcSetting;
-    private final IdentityBackend backend;
-
-    /**
-     * Construct with prepared KdcConfig and BackendConfig.
-     *
-     * @param kdcConfig     The kdc config
-     * @param backendConfig The backend config
-     * @throws KrbException e
-     */
-    public LocalKadminImpl(KdcConfig kdcConfig,
-                           BackendConfig backendConfig) throws KrbException {
-        this.backend = KdcUtil.getBackend(backendConfig);
-        this.kdcSetting = new KdcSetting(kdcConfig, backendConfig);
-    }
-
-    /**
-     * Construct with prepared conf dir.
-     *
-     * @param confDir The path of conf dir
-     * @throws KrbException e
-     */
-    public LocalKadminImpl(File confDir) throws KrbException {
-        KdcConfig tmpKdcConfig = KdcUtil.getKdcConfig(confDir);
-        if (tmpKdcConfig == null) {
-            tmpKdcConfig = new KdcConfig();
-        }
-
-        BackendConfig tmpBackendConfig = KdcUtil.getBackendConfig(confDir);
-        if (tmpBackendConfig == null) {
-            tmpBackendConfig = new BackendConfig();
-        }
-
-        this.kdcSetting = new KdcSetting(tmpKdcConfig, tmpBackendConfig);
-
-        backend = KdcUtil.getBackend(tmpBackendConfig);
-    }
-
-    /**
-     * Construct with prepared KdcSetting and Backend.
-     *
-     * @param kdcSetting The kdc setting
-     * @param backend    The identity backend
-     */
-    public LocalKadminImpl(KdcSetting kdcSetting, IdentityBackend backend) {
-        this.kdcSetting = kdcSetting;
-        this.backend = backend;
-    }
-
-    /**
-     * Get the tgs principal name.
-     */
-    private String getTgsPrincipal() {
-        return KrbUtil.makeTgsPrincipal(kdcSetting.getKdcRealm()).getName();
-    }
-
-    @Override
-    public String getKadminPrincipal() {
-        return KrbUtil.makeKadminPrincipal(kdcSetting.getKdcRealm()).getName();
-    }
-
-    @Override
-    public void checkBuiltinPrincipals() throws KrbException {
-        String tgsPrincipal = getTgsPrincipal();
-        String kadminPrincipal = getKadminPrincipal();
-        if (backend.getIdentity(tgsPrincipal) == null
-            || backend.getIdentity(kadminPrincipal) == null) {
-            String errorMsg = "The built-in principals do not exist in backend,"
-                + " please run the kdcinit tool.";
-            LOG.error(errorMsg);
-            throw new KrbException(errorMsg);
-        }
-    }
-
-    @Override
-    public void createBuiltinPrincipals() throws KrbException {
-        String tgsPrincipal = getTgsPrincipal();
-        if (backend.getIdentity(tgsPrincipal) == null) {
-            addPrincipal(tgsPrincipal);
-        } else {
-            String errorMsg = "The tgs principal already exists in backend.";
-            LOG.error(errorMsg);
-            throw new KrbException(errorMsg);
-        }
-
-        String kadminPrincipal = getKadminPrincipal();
-        if (backend.getIdentity(kadminPrincipal) == null) {
-            addPrincipal(kadminPrincipal);
-        } else {
-            String errorMsg = "The kadmin principal already exists in backend.";
-            LOG.error(errorMsg);
-            throw new KrbException(errorMsg);
-        }
-    }
-
-    @Override
-    public void deleteBuiltinPrincipals() throws KrbException {
-        deletePrincipal(getTgsPrincipal());
-        deletePrincipal(getKadminPrincipal());
-    }
-
-    @Override
-    public KdcConfig getKdcConfig() {
-        return kdcSetting.getKdcConfig();
-    }
-
-    @Override
-    public BackendConfig getBackendConfig() {
-        return kdcSetting.getBackendConfig();
-    }
-
-    @Override
-    public IdentityBackend getIdentityBackend() {
-        return backend;
-    }
-
-    @Override
-    public void addPrincipal(String principal) throws KrbException {
-        principal = fixPrincipal(principal);
-        addPrincipal(principal, new KOptions());
-    }
-
-    @Override
-    public void addPrincipal(String principal, KOptions kOptions)
-            throws KrbException {
-        principal = fixPrincipal(principal);
-        KrbIdentity identity = AdminHelper.createIdentity(principal, kOptions);
-        List<EncryptionKey> keys = EncryptionUtil.generateKeys(
-                getKdcConfig().getEncryptionTypes());
-        identity.addKeys(keys);
-        backend.addIdentity(identity);
-    }
-
-    @Override
-    public void addPrincipal(String principal, String password)
-            throws KrbException {
-        principal = fixPrincipal(principal);
-        addPrincipal(principal, password, new KOptions());
-    }
-
-    @Override
-    public void addPrincipal(String principal, String password, KOptions kOptions)
-            throws KrbException {
-        principal = fixPrincipal(principal);
-        KrbIdentity identity = AdminHelper.createIdentity(principal, kOptions);
-        List<EncryptionKey> keys = EncryptionUtil.generateKeys(principal, password,
-                getKdcConfig().getEncryptionTypes());
-        identity.addKeys(keys);
-        backend.addIdentity(identity);
-    }
-
-    @Override
-    public void exportKeytab(File keytabFile, String principal)
-            throws KrbException {
-        principal = fixPrincipal(principal);
-        List<String> principals = new ArrayList<>(1);
-        principals.add(principal);
-        exportKeytab(keytabFile, principals);
-    }
-
-    @Override
-    public void exportKeytab(File keytabFile, List<String> principals)
-            throws KrbException {
-        //Get Identity
-        List<KrbIdentity> identities = new LinkedList<>();
-        for (String principal : principals) {
-            KrbIdentity identity = backend.getIdentity(principal);
-            if (identity == null) {
-                throw new KrbException("Can not find the identity for pincipal "
-                        + principal);
-            }
-            identities.add(identity);
-        }
-
-        AdminHelper.exportKeytab(keytabFile, identities);
-    }
-
-    @Override
-    public void exportKeytab(File keytabFile) throws KrbException {
-        Keytab keytab = AdminHelper.createOrLoadKeytab(keytabFile);
-
-        Iterable<String> principals = backend.getIdentities();
-        for (String principal : principals) {
-            KrbIdentity identity = backend.getIdentity(principal);
-            if (identity != null) {
-                AdminHelper.exportToKeytab(keytab, identity);
-            }
-        }
-
-        AdminHelper.storeKeytab(keytab, keytabFile);
-    }
-
-    @Override
-    public void removeKeytabEntriesOf(File keytabFile, String principal)
-            throws KrbException {
-        principal = fixPrincipal(principal);
-        AdminHelper.removeKeytabEntriesOf(keytabFile, principal);
-    }
-
-    @Override
-    public void removeKeytabEntriesOf(File keytabFile, String principal, int kvno)
-            throws KrbException {
-        principal = fixPrincipal(principal);
-        AdminHelper.removeKeytabEntriesOf(keytabFile, principal, kvno);
-    }
-
-    @Override
-    public void removeOldKeytabEntriesOf(File keytabFile, String principal)
-            throws KrbException {
-        principal = fixPrincipal(principal);
-        AdminHelper.removeOldKeytabEntriesOf(keytabFile, principal);
-    }
-
-    @Override
-    public void deletePrincipal(String principal) throws KrbException {
-        principal = fixPrincipal(principal);
-        backend.deleteIdentity(principal);
-    }
-
-    @Override
-    public void modifyPrincipal(String principal, KOptions kOptions)
-            throws KrbException {
-        principal = fixPrincipal(principal);
-        KrbIdentity identity = backend.getIdentity(principal);
-        if (identity == null) {
-            throw new KrbException("Principal \""
-                    + principal + "\" does not exist.");
-        }
-        AdminHelper.updateIdentity(identity, kOptions);
-        backend.updateIdentity(identity);
-    }
-
-    @Override
-    public void renamePrincipal(String oldPrincipalName, String newPrincipalName)
-            throws KrbException {
-        oldPrincipalName = fixPrincipal(oldPrincipalName);
-        newPrincipalName = fixPrincipal(newPrincipalName);
-        KrbIdentity oldIdentity = backend.getIdentity(newPrincipalName);
-        if (oldIdentity != null) {
-            throw new KrbException("Principal \""
-                    + oldIdentity.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);
-    }
-
-    @Override
-    public KrbIdentity getPrincipal(String principalName) throws KrbException {
-        KrbIdentity identity = backend.getIdentity(principalName);
-        return identity;
-    }
-
-    @Override
-    public List<String> getPrincipals() throws KrbException {
-        Iterable<String> principalNames = backend.getIdentities();
-        List<String> principalList = new LinkedList<>();
-        Iterator<String> iterator = principalNames.iterator();
-        while (iterator.hasNext()) {
-            principalList.add(iterator.next());
-        }
-        return principalList;
-    }
-
-    @Override
-    public List<String> getPrincipals(String globString) throws KrbException {
-        Pattern pt = AdminHelper.getPatternFromGlobPatternString(globString);
-        if (pt == null) {
-            return getPrincipals();
-        }
-
-        Boolean containsAt = pt.pattern().indexOf('@') != -1;
-        List<String> result = new LinkedList<>();
-
-        List<String> principalNames = getPrincipals();
-        for (String principal: principalNames) {
-            String toMatch = containsAt ? principal : principal.split("@")[0];
-            Matcher m = pt.matcher(toMatch);
-            if (m.matches()) {
-                result.add(principal);
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public void changePassword(String principal,
-                               String newPassword) throws KrbException {
-        principal = fixPrincipal(principal);
-        KrbIdentity identity = backend.getIdentity(principal);
-        if (identity == null) {
-            throw new KrbException("Principal " + principal
-                    + "was not found. Please check the input and try again");
-        }
-        List<EncryptionKey> keys = EncryptionUtil.generateKeys(principal, newPassword,
-                getKdcConfig().getEncryptionTypes());
-        identity.addKeys(keys);
-
-        backend.updateIdentity(identity);
-    }
-
-    @Override
-    public void updateKeys(String principal) throws KrbException {
-        principal = fixPrincipal(principal);
-        KrbIdentity identity = backend.getIdentity(principal);
-        if (identity == null) {
-            throw new KrbException("Principal " + principal
-                    + "was not found. Please check the input and try again");
-        }
-        List<EncryptionKey> keys = EncryptionUtil.generateKeys(
-                getKdcConfig().getEncryptionTypes());
-        identity.addKeys(keys);
-        backend.updateIdentity(identity);
-    }
-
-    @Override
-    public void release() throws KrbException {
-        if (backend != null) {
-            backend.stop();
-        }
-    }
-
-    /**
-     * get size of principal
-     */
-    @Override
-    public int size() throws KrbException {
-        return this.getPrincipals().size();
-    }
-
-    /**
-     * Fix principal name, making it complete.
-     *
-     * @param principal The principal name
-     */
-    private String fixPrincipal(String principal) {
-        if (!principal.contains("@")) {
-            principal += "@" + kdcSetting.getKdcRealm();
-        }
-        return principal;
-    }
-}