directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From plusplusjia...@apache.org
Subject [1/2] directory-kerby git commit: DIRKRB-675 Implement remote kadmin tool based on kadmin client.
Date Mon, 12 Mar 2018 01:52:47 GMT
Repository: directory-kerby
Updated Branches:
  refs/heads/trunk 7169e93c2 -> ca88971b9


DIRKRB-675 Implement remote kadmin tool based on kadmin client.


Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/488f15a6
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/488f15a6
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/488f15a6

Branch: refs/heads/trunk
Commit: 488f15a6062ec503cd88b2ed08e583a82a084cbe
Parents: 2da23fc
Author: plusplusjiajia <jiajia.li@intel.com>
Authored: Mon Mar 12 09:49:07 2018 +0800
Committer: plusplusjiajia <jiajia.li@intel.com>
Committed: Mon Mar 12 09:49:07 2018 +0800

----------------------------------------------------------------------
 .../kerby/has/client/HasAuthAdminClient.java    |  22 ++--
 .../org/apache/kerby/has/client/HasClient.java  |   2 +-
 .../apache/kerby/has/common/util/HasUtil.java   |   5 +-
 .../org/apache/kerby/has/server/HasServer.java  |  93 +++++++------
 .../apache/kerby/has/server/web/WebServer.java  |   5 +-
 .../kerby/has/server/web/rest/KadminApi.java    |  45 ++++---
 kerby-dist/has-dist/bin/admin-remote.sh         |  56 ++++++++
 kerby-dist/has-dist/bin/has-init.sh             |   4 +-
 kerby-dist/has-dist/conf/admin.conf             |   6 +
 kerby-dist/has-dist/conf/hadmin.conf            |   6 -
 kerby-dist/has-dist/conf/has-server.conf        |   2 +-
 kerby-dist/has-dist/conf/kdc.conf               |   2 +-
 kerby-dist/has-dist/conf/krb5.conf              |   2 +-
 .../apache/kerby/kerberos/tool/HasInitTool.java | 108 ---------------
 .../kerberos/tool/admin/AdminRemoteTool.java    | 132 +++++++++++++++++++
 .../tool/admin/cmd/AddPrincipalRemoteCmd.java   |  65 +++++++++
 .../kerberos/tool/admin/cmd/AdminRemoteCmd.java |  42 ++++++
 .../admin/cmd/DeletePrincipalRemoteCmd.java     |  83 ++++++++++++
 .../tool/admin/cmd/ListPrincipalsRemoteCmd.java |  70 ++++++++++
 .../admin/cmd/RenamePrincipalRemoteCmd.java     |  85 ++++++++++++
 .../apache/kerby/kerberos/tool/cmd/InitCmd.java |  42 ------
 .../kerby/kerberos/tool/cmd/InitKdcCmd.java     |  86 ------------
 .../kerby/kerberos/tool/cmd/StartKdcCmd.java    |  52 --------
 .../kerby/kerberos/tool/init/HasInitTool.java   | 108 +++++++++++++++
 .../kerby/kerberos/tool/init/cmd/InitCmd.java   |  42 ++++++
 .../kerberos/tool/init/cmd/InitKdcCmd.java      |  85 ++++++++++++
 .../kerberos/tool/init/cmd/StartKdcCmd.java     |  52 ++++++++
 27 files changed, 924 insertions(+), 378 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasAuthAdminClient.java
----------------------------------------------------------------------
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasAuthAdminClient.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasAuthAdminClient.java
index 1ce0c4d..e9a7dc9 100644
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasAuthAdminClient.java
+++ b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasAuthAdminClient.java
@@ -87,7 +87,7 @@ public class HasAuthAdminClient implements Kadmin {
             try {
                 conn = getHttpsConnection(url, true);
             } catch (Exception e) {
-                throw new RuntimeException("Error occurred when creating https connection.");
+                throw new RuntimeException("Error occurred when creating https connection. " + e.getMessage());
             }
         }
         if (method.equals("POST") || method.equals("PUT")) {
@@ -96,11 +96,11 @@ public class HasAuthAdminClient implements Kadmin {
         return conn;
     }
 
-    private String getBaseURL() {
+    private String getKadminBaseURL() {
         String url = null;
         if (hasConfig.getHttpsPort() != null && hasConfig.getHttpsHost() != null) {
             url = "https://" + hasConfig.getHttpsHost() + ":" + hasConfig.getHttpsPort()
-                + "/has/v1/admin/";
+                + "/has/v1/kadmin/";
         }
         if (url == null) {
             throw new RuntimeException("Please set the https address and port.");
@@ -114,7 +114,7 @@ public class HasAuthAdminClient implements Kadmin {
 
         URL url;
         try {
-            url = new URL(getBaseURL() + "addprincipal?principal=" + principal);
+            url = new URL(getKadminBaseURL() + "addprincipal?principal=" + principal);
         } catch (MalformedURLException e) {
             throw new KrbException("Failed to create a URL object.", e);
         }
@@ -150,7 +150,7 @@ public class HasAuthAdminClient implements Kadmin {
 
         URL url;
         try {
-            url = new URL(getBaseURL() + "addprincipal?principal=" + principal
+            url = new URL(getKadminBaseURL() + "addprincipal?principal=" + principal
                 + "&password=" + password);
         } catch (MalformedURLException e) {
             throw new KrbException("Failed to create a URL object.", e);
@@ -191,7 +191,7 @@ public class HasAuthAdminClient implements Kadmin {
 
         URL url;
         try {
-            url = new URL(getBaseURL() + "deleteprincipal?principal=" + principal);
+            url = new URL(getKadminBaseURL() + "deleteprincipal?principal=" + principal);
         } catch (MalformedURLException e) {
             throw new KrbException("Failed to create a URL object.", e);
         }
@@ -231,7 +231,7 @@ public class HasAuthAdminClient implements Kadmin {
 
         URL url;
         try {
-            url = new URL(getBaseURL() + "renameprincipal?oldprincipal=" + oldPrincipal
+            url = new URL(getKadminBaseURL() + "renameprincipal?oldprincipal=" + oldPrincipal
                 + "&newprincipal=" + newPrincipal);
         } catch (MalformedURLException e) {
             throw new KrbException("Failed to create a URL object.", e);
@@ -267,7 +267,7 @@ public class HasAuthAdminClient implements Kadmin {
 
         URL url;
         try {
-            url = new URL(getBaseURL() + "getprincipals");
+            url = new URL(getKadminBaseURL() + "listprincipals");
         } catch (MalformedURLException e) {
             throw new KrbException("Failed to create a URL object.", e);
         }
@@ -304,7 +304,7 @@ public class HasAuthAdminClient implements Kadmin {
 
         URL url;
         try {
-            url = new URL(getBaseURL() + "getprincipals?exp=" + exp);
+            url = new URL(getKadminBaseURL() + "getprincipals?exp=" + exp);
         } catch (MalformedURLException e) {
             throw new KrbException("Failed to create a URL object. ", e);
         }
@@ -360,7 +360,7 @@ public class HasAuthAdminClient implements Kadmin {
     public void exportKeytab(File keytab, String principal) throws KrbException {
         URL url;
         try {
-            url = new URL(getBaseURL() + "exportkeytab?principal=" + principal);
+            url = new URL(getKadminBaseURL() + "exportkeytab?principal=" + principal);
         } catch (MalformedURLException e) {
             LOG.error("Failed to create a URL object." + e.getMessage());
             throw new KrbException("Failed to create a URL object.", e);
@@ -399,7 +399,7 @@ public class HasAuthAdminClient implements Kadmin {
     public void exportKeytab(File keytabFile, List<String> principals) throws KrbException {
         HttpURLConnection httpConn;
         for (String principal : principals) {
-            String request = getBaseURL() + "exportkeytab?principal=" + principal;
+            String request = getKadminBaseURL() + "exportkeytab?principal=" + principal;
             URL url;
             try {
                 url = new URL(request);

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClient.java
----------------------------------------------------------------------
diff --git a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClient.java b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClient.java
index e94ae5d..be0e804 100755
--- a/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClient.java
+++ b/has-project/has-client/src/main/java/org/apache/kerby/has/client/HasClient.java
@@ -121,7 +121,7 @@ public class HasClient {
                 config = HasUtil.getHasConfig(confFile);
             } catch (HasException e) {
                 LOG.error("Failed to get has client config: " + e.getMessage());
-                throw new HasException("Failed to get has client config: " + e);
+                throw new HasException("Failed to get has client config: " + e.getMessage());
             }
         } else {
             config = new HasConfig();

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
----------------------------------------------------------------------
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
index 19cbaea..6b01058 100644
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
+++ b/has-project/has-common/src/main/java/org/apache/kerby/has/common/util/HasUtil.java
@@ -50,9 +50,10 @@ public class HasUtil {
                     + hasConfFile.getAbsolutePath());
             }
             return hasConfig;
+        } else {
+            throw new HasException(hasConfFile.getName() + "not found in "
+                + hasConfFile.getParent() + ". ");
         }
-
-        return null;
     }
 
     public static void setEnableConf(File hasConfFile, String value)

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServer.java
----------------------------------------------------------------------
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServer.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServer.java
index 17cb8b4..121c7ca 100644
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServer.java
+++ b/has-project/has-server/src/main/java/org/apache/kerby/has/server/HasServer.java
@@ -143,6 +143,9 @@ public class HasServer {
 
     public File initKdcServer() throws KrbException {
         File adminKeytabFile = new File(workDir, "admin.keytab");
+        if (kdcServer == null) {
+            throw new KrbException("Please start KDC server first.");
+        }
         LocalKadmin kadmin = new LocalKadminImpl(kdcServer.getKdcSetting(),
             kdcServer.getIdentityService());
         if (adminKeytabFile.exists()) {
@@ -220,54 +223,50 @@ public class HasServer {
             // Parse has-server.conf to get http_host and http_port
             File confFile = new File(confDir, "has-server.conf");
             hasConfig = HasUtil.getHasConfig(confFile);
-            if (hasConfig != null) {
-                try {
-                    String httpHost;
-                    String httpPort;
-                    String httpsHost;
-                    String httpsPort;
-                    if (hasConfig.getHttpHost() != null) {
-                        httpHost = hasConfig.getHttpHost();
-                    } else {
-                        LOG.info("Cannot get the http_host from has-server.conf, using the default http host.");
-                        httpHost = WebConfigKey.HAS_HTTP_HOST_DEFAULT;
-                    }
-                    if (hasConfig.getHttpPort() != null) {
-                        httpPort = hasConfig.getHttpPort();
-                    } else {
-                        LOG.info("Cannot get the http_port from has-server.conf, using the default http port.");
-                        httpPort = String.valueOf(WebConfigKey.HAS_HTTP_PORT_DEFAULT);
-                    }
-                    if (hasConfig.getHttpsHost() != null) {
-                        httpsHost = hasConfig.getHttpsHost();
-                    } else {
-                        LOG.info("Cannot get the https_host from has-server.conf, using the default https host.");
-                        httpsHost = WebConfigKey.HAS_HTTPS_HOST_DEFAULT;
-                    }
-                    if (hasConfig.getHttpsPort() != null) {
-                        httpsPort = hasConfig.getHttpsPort();
-                    } else {
-                        LOG.info("Cannot get the https_port from has-server.conf , using the default https port.");
-                        httpsPort = String.valueOf(WebConfigKey.HAS_HTTPS_PORT_DEFAULT);
-                    }
-                    String hasHttpAddress = httpHost + ":" + httpPort;
-                    String hasHttpsAddress = httpsHost + ":" + httpsPort;
-                    LOG.info("The web server http address: " + hasHttpAddress);
-                    LOG.info("The web server https address: " + hasHttpsAddress);
-
-                    conf.setString(WebConfigKey.HAS_HTTP_ADDRESS_KEY, hasHttpAddress);
-                    conf.setString(WebConfigKey.HAS_HTTPS_ADDRESS_KEY, hasHttpsAddress);
-                    conf.setString(WebConfigKey.HAS_HTTP_POLICY_KEY,
-                        HttpConfig.Policy.HTTP_AND_HTTPS.name());
-                    conf.setString(WebConfigKey.HAS_SERVER_HTTPS_KEYSTORE_RESOURCE_KEY,
-                        hasConfig.getSslServerConf());
-                    webServer = new WebServer(conf);
-                } catch (NumberFormatException e) {
-                    throw new IllegalArgumentException("https_port should be a number. "
-                        + e.getMessage());
+            try {
+                String httpHost;
+                String httpPort;
+                String httpsHost;
+                String httpsPort;
+                if (hasConfig.getHttpHost() != null) {
+                    httpHost = hasConfig.getHttpHost();
+                } else {
+                    LOG.info("Cannot get the http_host from has-server.conf, using the default http host.");
+                    httpHost = WebConfigKey.HAS_HTTP_HOST_DEFAULT;
                 }
-            } else {
-                throw new HasException("has-server.conf not found in " + confDir + ". ");
+                if (hasConfig.getHttpPort() != null) {
+                    httpPort = hasConfig.getHttpPort();
+                } else {
+                    LOG.info("Cannot get the http_port from has-server.conf, using the default http port.");
+                    httpPort = String.valueOf(WebConfigKey.HAS_HTTP_PORT_DEFAULT);
+                }
+                if (hasConfig.getHttpsHost() != null) {
+                    httpsHost = hasConfig.getHttpsHost();
+                } else {
+                    LOG.info("Cannot get the https_host from has-server.conf, using the default https host.");
+                    httpsHost = WebConfigKey.HAS_HTTPS_HOST_DEFAULT;
+                }
+                if (hasConfig.getHttpsPort() != null) {
+                    httpsPort = hasConfig.getHttpsPort();
+                } else {
+                    LOG.info("Cannot get the https_port from has-server.conf , using the default https port.");
+                    httpsPort = String.valueOf(WebConfigKey.HAS_HTTPS_PORT_DEFAULT);
+                }
+                String hasHttpAddress = httpHost + ":" + httpPort;
+                String hasHttpsAddress = httpsHost + ":" + httpsPort;
+                LOG.info("The web server http address: " + hasHttpAddress);
+                LOG.info("The web server https address: " + hasHttpsAddress);
+
+                conf.setString(WebConfigKey.HAS_HTTP_ADDRESS_KEY, hasHttpAddress);
+                conf.setString(WebConfigKey.HAS_HTTPS_ADDRESS_KEY, hasHttpsAddress);
+                conf.setString(WebConfigKey.HAS_HTTP_POLICY_KEY,
+                    HttpConfig.Policy.HTTP_AND_HTTPS.name());
+                conf.setString(WebConfigKey.HAS_SERVER_HTTPS_KEYSTORE_RESOURCE_KEY,
+                    hasConfig.getSslServerConf());
+                webServer = new WebServer(conf);
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("https_port should be a number. "
+                    + e.getMessage());
             }
         } else {
             hasConfig = webServer.getConf();

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/WebServer.java
----------------------------------------------------------------------
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/WebServer.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/WebServer.java
index abf3a9a..1b1f9e6 100644
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/WebServer.java
+++ b/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/WebServer.java
@@ -81,9 +81,10 @@ public class WebServer {
 
             Map<String, String> params = getAuthFilterParams(conf);
 
-            String adminPathSpec = "/has/v1/admin/*";
+            String kadminPathSpec = "/has/v1/kadmin/*";
+            String hadminPathSpec = "/has/v1/hadmin/*";
             HttpServer2.defineFilter(httpServer.getWebAppContext(), name, className,
-                params, new String[]{adminPathSpec});
+                params, new String[]{kadminPathSpec, hadminPathSpec});
             HttpServer2.LOG.info("Added filter '" + name + "' (class=" + className
                 + ")");
         }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/KadminApi.java
----------------------------------------------------------------------
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/KadminApi.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/KadminApi.java
index 61c9a25..10ff6c8 100644
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/KadminApi.java
+++ b/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/KadminApi.java
@@ -25,7 +25,6 @@ import org.apache.kerby.kerberos.kerb.KrbException;
 import org.apache.kerby.kerberos.kerb.admin.kadmin.local.LocalKadminImpl;
 import org.apache.kerby.kerberos.kerb.server.KdcSetting;
 import org.codehaus.jettison.json.JSONArray;
-import org.codehaus.jettison.json.JSONObject;
 
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
@@ -98,12 +97,11 @@ public class KadminApi {
     }
 
     @GET
-    @Path("/getprincipals")
+    @Path("/listprincipals")
     @Produces(MediaType.APPLICATION_JSON)
-    public Response getprincipals(@QueryParam("exp") String exp) {
+    public Response listPrincipals(@QueryParam("exp") String exp) {
         if (httpRequest.isSecure()) {
             WebServer.LOG.info("Request to get principals.");
-            JSONObject result = new JSONObject();
             String msg;
             LocalKadminImpl localKadmin;
             HasServer hasServer = WebServer.getHasServerFromContext(context);
@@ -122,9 +120,7 @@ public class KadminApi {
                     principals.put(princ);
                 }
                 WebServer.LOG.info("Success to get principals with JSON.");
-                result.put("result", "success");
-                result.put("msg", principals.toString());
-                return Response.ok(result.toString()).build();
+                return Response.ok(principals.toString()).build();
             } catch (Exception e) {
                 msg = "Failed to get principals,because : " + e.getMessage();
                 WebServer.LOG.error(msg);
@@ -144,7 +140,7 @@ public class KadminApi {
     @POST
     @Path("/addprincipal")
     @Produces(MediaType.TEXT_PLAIN)
-    public Response addprincipal(@QueryParam(PrincipalParam.NAME) @DefaultValue(PrincipalParam.DEFAULT)
+    public Response addPrincipal(@QueryParam(PrincipalParam.NAME) @DefaultValue(PrincipalParam.DEFAULT)
                                  final PrincipalParam principal,
                                  @QueryParam(PasswordParam.NAME) @DefaultValue(PasswordParam.DEFAULT)
                                  final PasswordParam password) {
@@ -161,14 +157,31 @@ public class KadminApi {
                 WebServer.LOG.error(msg);
                 return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
             }
-            try {
-                localKadmin.addPrincipal(principal.getValue(), password.getValue());
-                msg = "Add principal successfully.";
-                return Response.ok(msg).build();
-            } catch (Exception e) {
-                msg = "Failed to add " + principal + " principal, because: " + e.getMessage();
+            if (principal.getValue() == null) {
+                msg = "Value of principal is null.";
                 WebServer.LOG.error(msg);
-                return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
+                return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
+            }
+            if (password.getValue() == null || password.getValue().equals("")) {
+                try {
+                    localKadmin.addPrincipal(principal.getValue());
+                    msg = "Add principal successfully.";
+                    return Response.ok(msg).build();
+                } catch (KrbException e) {
+                    msg = "Failed to add " + principal + " principal, because: " + e.getMessage();
+                    WebServer.LOG.error(msg);
+                    return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
+                }
+            } else {
+                try {
+                    localKadmin.addPrincipal(principal.getValue(), password.getValue());
+                    msg = "Add principal successfully.";
+                    return Response.ok(msg).build();
+                } catch (KrbException e) {
+                    msg = "Failed to add " + principal + " principal, because: " + e.getMessage();
+                    WebServer.LOG.error(msg);
+                    return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
+                }
             }
         }
         return Response.status(Response.Status.FORBIDDEN).entity("HTTPS required.\n").build();
@@ -222,7 +235,7 @@ public class KadminApi {
     @DELETE
     @Path("/deleteprincipal")
     @Produces(MediaType.TEXT_PLAIN)
-    public Response deleteprincipal(@QueryParam(PrincipalParam.NAME) @DefaultValue(PrincipalParam.DEFAULT)
+    public Response deletePrincipal(@QueryParam(PrincipalParam.NAME) @DefaultValue(PrincipalParam.DEFAULT)
                                     final PrincipalParam principal) {
         if (httpRequest.isSecure()) {
             WebServer.LOG.info("Request to delete the principal named " + principal.getValue());

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-dist/has-dist/bin/admin-remote.sh
----------------------------------------------------------------------
diff --git a/kerby-dist/has-dist/bin/admin-remote.sh b/kerby-dist/has-dist/bin/admin-remote.sh
new file mode 100644
index 0000000..6aebc81
--- /dev/null
+++ b/kerby-dist/has-dist/bin/admin-remote.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+
+# 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.
+
+CONF_DIR=$1
+APP_MAIN=org.apache.kerby.kerberos.tool.admin.AdminRemoteTool
+
+# Reset HAS_CONF_DIR if CONF_DIR not null
+if [ "$CONF_DIR" != "" ]; then
+  if [ ! -d "$CONF_DIR" ]; then
+    echo "[ERROR] ${CONF_DIR} is not a directory"
+    usage
+  fi
+else
+  if [ "$HAS_CONF_DIR" != "" ] && [ -d "$HAS_CONF_DIR" ]; then
+    CONF_DIR=${HAS_CONF_DIR}
+  else
+    echo "[ERROR] HAS_CONF_DIR is null or not a directory"
+    exit
+  fi
+fi
+
+# Load HAS environment variables
+if [ -f "${CONF_DIR}/has-env.sh" ]; then
+  . "${CONF_DIR}/has-env.sh"
+fi
+
+# Get HAS_HOME directory
+bin=`dirname "$0"`
+HAS_HOME=`cd ${bin}/..; pwd`
+cd ${HAS_HOME}
+
+for var in $*; do
+  if [ X"$var" = X"-D" ]; then
+    DEBUG="-Xdebug -Xrunjdwp:transport=dt_socket,address=8012,server=y,suspend=y"
+  fi
+done
+
+echo "[INFO] conf_dir=$CONF_DIR"
+HAS_OPTS="-DHAS_LOGFILE=admin-remote"
+
+java ${DEBUG} -classpath target/lib/*:. ${HAS_OPTS} ${APP_MAIN} ${CONF_DIR}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-dist/has-dist/bin/has-init.sh
----------------------------------------------------------------------
diff --git a/kerby-dist/has-dist/bin/has-init.sh b/kerby-dist/has-dist/bin/has-init.sh
index 2bbbf6a..176b4d6 100644
--- a/kerby-dist/has-dist/bin/has-init.sh
+++ b/kerby-dist/has-dist/bin/has-init.sh
@@ -17,7 +17,7 @@
 # limitations under the License.
 
 CONF_DIR=$1
-APP_MAIN=org.apache.kerby.kerberos.tool.HasInitTool
+APP_MAIN=org.apache.kerby.kerberos.tool.init.HasInitTool
 
 # Reset HAS_CONF_DIR if CONF_DIR not null
 if [ "$CONF_DIR" != "" ]; then
@@ -51,6 +51,6 @@ for var in $*; do
 done
 
 echo "[INFO] conf_dir=$CONF_DIR"
-HAS_OPTS="-DHAS_LOGFILE=kdcinit"
+HAS_OPTS="-DHAS_LOGFILE=has-init"
 
 java ${DEBUG} -classpath target/lib/*:. ${HAS_OPTS} ${APP_MAIN} ${CONF_DIR}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-dist/has-dist/conf/admin.conf
----------------------------------------------------------------------
diff --git a/kerby-dist/has-dist/conf/admin.conf b/kerby-dist/has-dist/conf/admin.conf
new file mode 100644
index 0000000..e950aea
--- /dev/null
+++ b/kerby-dist/has-dist/conf/admin.conf
@@ -0,0 +1,6 @@
+[HAS]
+    https_host = plusplus-desktop
+    https_port = 8092
+    admin_keytab = /etc/has/admin.keytab
+    admin_keytab_principal = kadmin/HADOOP.COM@HADOOP.COM
+    filter_auth_type = kerberos

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-dist/has-dist/conf/hadmin.conf
----------------------------------------------------------------------
diff --git a/kerby-dist/has-dist/conf/hadmin.conf b/kerby-dist/has-dist/conf/hadmin.conf
deleted file mode 100644
index 125bdfc..0000000
--- a/kerby-dist/has-dist/conf/hadmin.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-[HAS]
-    https_host = hostname
-    https_port = 8092
-    admin_keytab = /etc/has/admin.keytab
-    admin_keytab_principal = kadmin/HADOOP.COM@HADOOP.COM
-    filter_auth_type = kerberos

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-dist/has-dist/conf/has-server.conf
----------------------------------------------------------------------
diff --git a/kerby-dist/has-dist/conf/has-server.conf b/kerby-dist/has-dist/conf/has-server.conf
index 93accaf..43a83fb 100644
--- a/kerby-dist/has-dist/conf/has-server.conf
+++ b/kerby-dist/has-dist/conf/has-server.conf
@@ -20,5 +20,5 @@
   https_host = plusplus-desktop
   https_port = 8092
   filter_auth_type = kerberos
-  enable_conf = false
+  enable_conf = true
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-dist/has-dist/conf/kdc.conf
----------------------------------------------------------------------
diff --git a/kerby-dist/has-dist/conf/kdc.conf b/kerby-dist/has-dist/conf/kdc.conf
index 21ccdd1..a2132ac 100644
--- a/kerby-dist/has-dist/conf/kdc.conf
+++ b/kerby-dist/has-dist/conf/kdc.conf
@@ -17,7 +17,7 @@
 #
 
 [kdcdefaults]
-  kdc_host = hostname
+  kdc_host = plusplus-desktop
   kdc_udp_port = 88
   kdc_tcp_port = 88
   kdc_realm = HADOOP.COM

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-dist/has-dist/conf/krb5.conf
----------------------------------------------------------------------
diff --git a/kerby-dist/has-dist/conf/krb5.conf b/kerby-dist/has-dist/conf/krb5.conf
index 55ae355..6c64cf5 100644
--- a/kerby-dist/has-dist/conf/krb5.conf
+++ b/kerby-dist/has-dist/conf/krb5.conf
@@ -25,5 +25,5 @@
     ticket_lifetime = 60
 [realms]
     HADOOP.COM = {
-        kdc = hostname:88
+        kdc = plusplus-desktop:88
     }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/HasInitTool.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/HasInitTool.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/HasInitTool.java
deleted file mode 100644
index b94b618..0000000
--- a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/HasInitTool.java
+++ /dev/null
@@ -1,108 +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.tool;
-
-import org.apache.kerby.has.client.HasInitClient;
-import org.apache.kerby.has.common.HasConfig;
-import org.apache.kerby.has.common.HasException;
-import org.apache.kerby.has.common.util.HasUtil;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.tool.cmd.InitCmd;
-import org.apache.kerby.kerberos.tool.cmd.InitKdcCmd;
-import org.apache.kerby.kerberos.tool.cmd.StartKdcCmd;
-import org.apache.kerby.util.OSUtil;
-
-import java.io.File;
-import java.util.Scanner;
-
-public class HasInitTool {
-    private static final String PROMPT = HasInitTool.class.getSimpleName();
-    private static final String USAGE = (OSUtil.isWindows()
-            ? "Usage: bin\\hasinit.cmd" : "Usage: sh bin/hasinit.sh")
-            + " <conf-file>\n"
-            + "\tExample:\n"
-            + "\t\t"
-            + (OSUtil.isWindows()
-            ? "bin\\hasinit.cmd" : "sh bin/hasinit.sh")
-            + " conf\n";
-
-    private static final String LEGAL_COMMANDS = "Available commands are: "
-            + "\n"
-            + "start_kdc, start\n"
-            + "                         Start kdc\n"
-            + "init_kdc, init\n"
-            + "                         Init kdc\n";
-
-    public static void main(String[] args) {
-        if (args.length < 1) {
-            System.err.println(USAGE);
-            System.exit(1);
-        }
-        String confDirPath = args[0];
-        File confFile = new File(confDirPath, "hadmin.conf");
-        HasConfig hasConfig;
-        try {
-            hasConfig = HasUtil.getHasConfig(confFile);
-        } catch (HasException e) {
-            System.err.println(e.getMessage());
-            return;
-        }
-
-        System.out.println(LEGAL_COMMANDS);
-        System.out.println("enter \"<cmd> [?][-help]\" to get cmd help.");
-        Scanner scanner = new Scanner(System.in, "UTF-8");
-        System.out.print(PROMPT + ": ");
-        String input = scanner.nextLine();
-
-        HasInitClient hasInitClient = new HasInitClient(hasConfig, new File(confDirPath));
-        while (!(input.equals("quit") || input.equals("exit") || input.equals("q"))) {
-            try {
-                execute(hasInitClient, input);
-            } catch (KrbException e) {
-                System.err.println(e.getMessage());
-            }
-            System.out.print(PROMPT + ": ");
-            input = scanner.nextLine();
-        }
-    }
-
-    private static void execute(HasInitClient hasInitClient, String input) throws KrbException {
-        input = input.trim();
-        if (input.startsWith("cmd")) {
-            System.out.println(LEGAL_COMMANDS);
-            return;
-        }
-        String[] items = input.split("\\s+");
-        String cmd = items[0];
-
-        InitCmd executor;
-        if (cmd.equals("start_kdc")
-            || cmd.equals("start")) {
-            executor = new StartKdcCmd(hasInitClient);
-        } else if (cmd.equals("init_kdc")
-            || cmd.equals("init")) {
-            executor = new InitKdcCmd(hasInitClient);
-        } else {
-            System.out.println(LEGAL_COMMANDS);
-            return;
-        }
-        executor.execute(items);
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/AdminRemoteTool.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/AdminRemoteTool.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/AdminRemoteTool.java
new file mode 100644
index 0000000..fc2356c
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/AdminRemoteTool.java
@@ -0,0 +1,132 @@
+/**
+ *  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.tool.admin;
+
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasConfig;
+import org.apache.kerby.has.common.HasException;
+import org.apache.kerby.has.common.util.HasUtil;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.tool.admin.cmd.AddPrincipalRemoteCmd;
+import org.apache.kerby.kerberos.tool.admin.cmd.AdminRemoteCmd;
+import org.apache.kerby.kerberos.tool.admin.cmd.DeletePrincipalRemoteCmd;
+import org.apache.kerby.kerberos.tool.admin.cmd.ListPrincipalsRemoteCmd;
+import org.apache.kerby.kerberos.tool.admin.cmd.RenamePrincipalRemoteCmd;
+import org.apache.kerby.util.OSUtil;
+
+import java.io.File;
+import java.util.Scanner;
+
+public class AdminRemoteTool {
+
+    private static final String PROMPT = "admin.remote";
+    private static final String USAGE = (OSUtil.isWindows()
+        ? "Usage: bin\\admin-remote.cmd" : "Usage: sh bin/admin-remote.sh")
+        + " <conf-file>\n"
+        + "\tExample:\n"
+        + "\t\t"
+        + (OSUtil.isWindows()
+        ? "bin\\admin-remote.cmd" : "sh bin/admin-remote.sh")
+        + " conf\n";
+
+    private static final String LEGAL_COMMANDS = "Available commands are: "
+        + "\n"
+        + "add_principal, addprinc\n"
+        + "                         Add principal\n"
+        + "delete_principal, delprinc\n"
+        + "                         Delete principal\n"
+        + "rename_principal, renprinc\n"
+        + "                         Rename principal\n"
+        + "list_principals, listprincs\n"
+        + "                         List principals\n";
+
+    public static void main(String[] args) {
+
+        HasAuthAdminClient authHasAdminClient = null;
+
+        if (args.length < 1) {
+            System.err.println(USAGE);
+            System.exit(1);
+        }
+
+        String confDirPath = args[0];
+        File confFile = new File(confDirPath, "admin.conf");
+        HasConfig hasConfig;
+        try {
+            hasConfig = HasUtil.getHasConfig(confFile);
+        } catch (HasException e) {
+            System.err.println(e.getMessage());
+            return;
+        }
+
+        if (hasConfig.getFilterAuthType().equals("kerberos")) {
+            authHasAdminClient = new HasAuthAdminClient(hasConfig);
+        }
+
+        System.out.println("enter \"cmd\" to see legal commands.");
+        System.out.print(PROMPT + ": ");
+
+        try (Scanner scanner = new Scanner(System.in, "UTF-8")) {
+            String input = scanner.nextLine();
+
+            while (!(input.equals("quit") || input.equals("exit") || input.equals("q"))) {
+                try {
+                    execute(authHasAdminClient, input);
+                } catch (KrbException e) {
+                    System.err.println(e.getMessage());
+                }
+                System.out.print(PROMPT + ": ");
+                input = scanner.nextLine();
+            }
+        }
+    }
+
+    private static void execute(HasAuthAdminClient hasAuthAdminClient,
+                               String input) throws KrbException {
+        input = input.trim();
+        if (input.startsWith("cmd")) {
+            System.out.println(LEGAL_COMMANDS);
+            return;
+        }
+        AdminRemoteCmd executor;
+
+        String[] items = input.split("\\s+");
+        String cmd = items[0];
+
+        if (cmd.equals("add_principal")
+            || cmd.equals("addprinc")) {
+            executor = new AddPrincipalRemoteCmd(hasAuthAdminClient);
+        } else if (cmd.equals("delete_principal")
+            || cmd.equals("delprinc")) {
+            executor = new DeletePrincipalRemoteCmd(hasAuthAdminClient);
+        } else if (cmd.equals("rename_principal")
+            || cmd.equals("renprinc")) {
+            executor = new RenamePrincipalRemoteCmd(hasAuthAdminClient);
+        } else if (cmd.equals("list_principals")
+            || cmd.equals("listprincs")) {
+            executor = new ListPrincipalsRemoteCmd(hasAuthAdminClient);
+        } else {
+            System.out.println(LEGAL_COMMANDS);
+            return;
+        }
+        executor.execute(items);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AddPrincipalRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AddPrincipalRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AddPrincipalRemoteCmd.java
new file mode 100644
index 0000000..6cbe325
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AddPrincipalRemoteCmd.java
@@ -0,0 +1,65 @@
+/**
+ *  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.tool.admin.cmd;
+
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+/**
+ * Remote add principal cmd
+ */
+public class AddPrincipalRemoteCmd extends AdminRemoteCmd {
+
+    public static final String USAGE = "Usage: add_principal [options] <principal-name>\n"
+        + "\toptions are:\n"
+        + "\t\t[-randkey]\n"
+        + "\t\t[-pw password]"
+        + "\tExample:\n"
+        + "\t\tadd_principal -pw mypassword alice\n";
+
+    public AddPrincipalRemoteCmd(HasAuthAdminClient authHadmin) {
+        super(authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        if (items.length < 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        String clientPrincipal = items[items.length - 1];
+
+        HasAuthAdminClient client = getAuthAdminClient();
+
+
+        if (!items[1].startsWith("-")) {
+            client.addPrincipal(clientPrincipal);
+        } else if (items[1].startsWith("-randkey")) {
+            client.addPrincipal(clientPrincipal);
+        } else if (items[1].startsWith("-pw")) {
+            String password = items[2];
+            client.addPrincipal(clientPrincipal, password);
+        } else {
+            System.err.println("add_principal cmd format error.");
+            System.err.println(USAGE);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AdminRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AdminRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AdminRemoteCmd.java
new file mode 100644
index 0000000..b5ccee4
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AdminRemoteCmd.java
@@ -0,0 +1,42 @@
+/**
+ *  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.tool.admin.cmd;
+
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+public abstract class AdminRemoteCmd {
+
+    private HasAuthAdminClient client;
+
+    public AdminRemoteCmd(HasAuthAdminClient authHadminClient) {
+        this.client = authHadminClient;
+    }
+
+    protected HasAuthAdminClient getAuthAdminClient() {
+        return client;
+    }
+
+    /**
+     * Execute the admin cmd.
+     * @param input Input cmd to execute
+     */
+    public abstract void execute(String[] input) throws KrbException;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/DeletePrincipalRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/DeletePrincipalRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/DeletePrincipalRemoteCmd.java
new file mode 100644
index 0000000..fee5b0d
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/DeletePrincipalRemoteCmd.java
@@ -0,0 +1,83 @@
+/**
+ *  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.tool.admin.cmd;
+
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import java.io.Console;
+import java.util.Scanner;
+
+/**
+ * Remote delete principal cmd
+ */
+public class DeletePrincipalRemoteCmd extends AdminRemoteCmd {
+
+    public static final String USAGE = "Usage: delete_principal <principal-name>\n"
+        + "\tExample:\n"
+        + "\t\tdelete_principal alice\n";
+
+    public DeletePrincipalRemoteCmd(HasAuthAdminClient authHadmin) {
+        super(authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        if (items.length < 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        HasAuthAdminClient client = getAuthAdminClient();
+
+        String principal = items[items.length - 1];
+        String reply;
+        Console console = System.console();
+        String prompt = "Are you sure to delete the principal? (yes/no, YES/NO, y/n, Y/N) ";
+        if (console == null) {
+            System.out.println("Couldn't get Console instance, "
+                + "maybe you're running this from within an IDE. "
+                + "Use scanner to read password.");
+            Scanner scanner = new Scanner(System.in, "UTF-8");
+            reply = getReply(scanner, prompt);
+        } else {
+            reply = getReply(console, prompt);
+        }
+        if (reply.equals("yes") || reply.equals("YES") || reply.equals("y") || reply.equals("Y")) {
+            client.deletePrincipal(principal);
+        } else if (reply.equals("no") || reply.equals("NO") || reply.equals("n") || reply.equals("N")) {
+            System.out.println("Principal \"" + principal + "\"  not deleted.");
+        } else {
+            System.err.println("Unknown request, fail to delete the principal.");
+            System.err.println(USAGE);
+        }
+    }
+
+    private String getReply(Scanner scanner, String prompt) {
+        System.out.println(prompt);
+        return scanner.nextLine().trim();
+    }
+
+    private String getReply(Console console, String prompt) {
+        console.printf(prompt);
+        String line = console.readLine();
+        return line;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/ListPrincipalsRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/ListPrincipalsRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/ListPrincipalsRemoteCmd.java
new file mode 100644
index 0000000..b46f95c
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/ListPrincipalsRemoteCmd.java
@@ -0,0 +1,70 @@
+/**
+ *  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.tool.admin.cmd;
+
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import java.util.List;
+
+public class ListPrincipalsRemoteCmd extends AdminRemoteCmd {
+    private static final String USAGE = "Usage: list_principals [expression]\n"
+            + "\t'expression' is a shell-style glob expression that can contain the wild-card characters ?, *, and []."
+            + "\tExample:\n"
+            + "\t\tlist_principals [expression]\n";
+
+    public ListPrincipalsRemoteCmd(HasAuthAdminClient authHadmin) {
+        super(authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        if (items.length > 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        HasAuthAdminClient client = getAuthAdminClient();
+
+        List<String> principalLists = null;
+
+        if (items.length == 1) {
+            try {
+                principalLists = client.getPrincipals();
+            } catch (Exception e) {
+                System.err.println("Errors occurred when getting the principals. " + e.getMessage());
+            }
+        } else {
+            //have expression
+            String exp = items[1];
+            principalLists = client.getPrincipals(exp);
+        }
+
+        if (principalLists.size() == 0 || principalLists.size() == 1 && principalLists.get(0).isEmpty()) {
+            return;
+        } else {
+            System.out.println("Principals are listed:");
+            for (int i = 0; i < principalLists.size(); i++) {
+                System.out.println(principalLists.get(i));
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/RenamePrincipalRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/RenamePrincipalRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/RenamePrincipalRemoteCmd.java
new file mode 100644
index 0000000..0be563e
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/RenamePrincipalRemoteCmd.java
@@ -0,0 +1,85 @@
+/**
+ *  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.tool.admin.cmd;
+
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import java.io.Console;
+import java.util.Scanner;
+
+/**
+ * Remote rename principal cmd
+ */
+public class RenamePrincipalRemoteCmd extends AdminRemoteCmd {
+    public static final String USAGE = "Usage: rename_principal <old_principal_name>"
+        + " <new_principal_name>\n"
+        + "\tExample:\n"
+        + "\t\trename_principal alice bob\n";
+
+    public RenamePrincipalRemoteCmd(HasAuthAdminClient client) {
+        super(client);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        if (items.length < 3) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        HasAuthAdminClient client = getAuthAdminClient();
+
+        String oldPrincipalName = items[items.length - 2];
+        String newPrincipalName = items[items.length - 1];
+
+        String reply;
+        Console console = System.console();
+        String prompt = "Are you sure to rename the principal? (yes/no, YES/NO, y/n, Y/N) ";
+        if (console == null) {
+            System.out.println("Couldn't get Console instance, "
+                + "maybe you're running this from within an IDE. "
+                + "Use scanner to read password.");
+            Scanner scanner = new Scanner(System.in, "UTF-8");
+            reply = getReply(scanner, prompt);
+        } else {
+            reply = getReply(console, prompt);
+        }
+        if (reply.equals("yes") || reply.equals("YES") || reply.equals("y") || reply.equals("Y")) {
+            client.renamePrincipal(oldPrincipalName, newPrincipalName);
+        } else if (reply.equals("no") || reply.equals("NO") || reply.equals("n") || reply.equals("N")) {
+            System.out.println("Principal \"" + oldPrincipalName + "\"  not renamed.");
+        } else {
+            System.err.println("Unknown request, fail to rename the principal.");
+            System.err.println(USAGE);
+        }
+    }
+
+    private String getReply(Scanner scanner, String prompt) {
+        System.out.println(prompt);
+        return scanner.nextLine().trim();
+    }
+
+    private String getReply(Console console, String prompt) {
+        console.printf(prompt);
+        String line = console.readLine();
+        return line;
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/InitCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/InitCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/InitCmd.java
deleted file mode 100644
index c03d5bd..0000000
--- a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/InitCmd.java
+++ /dev/null
@@ -1,42 +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.tool.cmd;
-
-import org.apache.kerby.has.client.HasInitClient;
-import org.apache.kerby.kerberos.kerb.KrbException;
-
-public abstract class InitCmd {
-
-    private HasInitClient client;
-
-    public InitCmd(HasInitClient client) {
-        this.client = client;
-    }
-
-    protected HasInitClient getClient() {
-        return client;
-    }
-
-    /**
-     * Execute the kdc init cmd.
-     * @param input Input cmd to execute
-     */
-    public abstract void execute(String[] input) throws KrbException;
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/InitKdcCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/InitKdcCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/InitKdcCmd.java
deleted file mode 100644
index 7f13073..0000000
--- a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/InitKdcCmd.java
+++ /dev/null
@@ -1,86 +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.tool.cmd;
-
-import org.apache.kerby.has.client.HasInitClient;
-import org.apache.kerby.kerberos.kerb.KrbException;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Remote init kdc cmd
- */
-public class InitKdcCmd extends InitCmd {
-
-    public static final String USAGE = "Usage: init_kdc [-p] [path]\n"
-        + "\tExample:\n"
-        + "\t\tinit_kdc\n";
-
-    public InitKdcCmd(HasInitClient client) {
-        super(client);
-    }
-
-    @Override
-    public void execute(String[] items) throws KrbException {
-        if (items.length >= 2 && (items[1].startsWith("?") || items[1].startsWith("-help"))) {
-                System.out.println(USAGE);
-            return;
-        }
-        File path = getClient().getConfDir();
-        if (items.length >= 3 && items[1].startsWith("-p")) {
-            path = new File(items[2]);
-            if (!path.exists() && !path.mkdirs()) {
-                System.err.println("Cannot create file : " + items[2]);
-                return;
-            }
-        }
-        File adminKeytab = new File(path, "admin.keytab");
-
-        HasInitClient client = getClient();
-        InputStream content = client.initKdc();
-
-        if (content == null) {
-            System.err.println("Failed to init kdc.");
-            return;
-        }
-
-        try (FileOutputStream fos = new FileOutputStream(adminKeytab)) {
-            byte[] buffer = new byte[4 * 1024];
-            int read;
-            while ((read = content.read(buffer)) > 0) {
-                fos.write(buffer, 0, read);
-            }
-            fos.close();
-            content.close();
-        } catch (FileNotFoundException e) {
-            System.err.println("the admin keytab file not found. " + e.getMessage());
-        } catch (IOException e) {
-            System.err.println("Errors occurred when getting the admin.keytab. " + e.getMessage());
-        }
-
-        System.out.println("admin.keytab has saved in : " + adminKeytab.getAbsolutePath()
-            + ",\nplease safely save it to use kadmin.");
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/StartKdcCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/StartKdcCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/StartKdcCmd.java
deleted file mode 100644
index 05c9932..0000000
--- a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/cmd/StartKdcCmd.java
+++ /dev/null
@@ -1,52 +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.tool.cmd;
-
-import org.apache.kerby.has.client.HasInitClient;
-import org.apache.kerby.kerberos.kerb.KrbException;
-
-/**
- * Remote start kdc cmd
- */
-public class StartKdcCmd extends InitCmd {
-
-    public static final String USAGE = "Usage: start_kdc\n"
-        + "\tExample:\n"
-        + "\t\tstart\n";
-
-    public StartKdcCmd(HasInitClient client) {
-        super(client);
-    }
-
-    @Override
-    public void execute(String[] items) throws KrbException {
-        if (items.length >= 2 && (items[1].startsWith("?") || items[1].startsWith("-help"))) {
-                System.out.println(USAGE);
-                return;
-        }
-
-        if (items.length != 1) {
-            System.err.println(USAGE);
-            return;
-        }
-        HasInitClient client = getClient();
-        client.startKdc();
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/HasInitTool.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/HasInitTool.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/HasInitTool.java
new file mode 100644
index 0000000..977d16d
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/HasInitTool.java
@@ -0,0 +1,108 @@
+/**
+ *  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.tool.init;
+
+import org.apache.kerby.has.client.HasInitClient;
+import org.apache.kerby.has.common.HasConfig;
+import org.apache.kerby.has.common.HasException;
+import org.apache.kerby.has.common.util.HasUtil;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.tool.init.cmd.InitCmd;
+import org.apache.kerby.kerberos.tool.init.cmd.InitKdcCmd;
+import org.apache.kerby.kerberos.tool.init.cmd.StartKdcCmd;
+import org.apache.kerby.util.OSUtil;
+
+import java.io.File;
+import java.util.Scanner;
+
+public class HasInitTool {
+    private static final String PROMPT = HasInitTool.class.getSimpleName();
+    private static final String USAGE = (OSUtil.isWindows()
+            ? "Usage: bin\\hasinit.cmd" : "Usage: sh bin/hasinit.sh")
+            + " <conf-file>\n"
+            + "\tExample:\n"
+            + "\t\t"
+            + (OSUtil.isWindows()
+            ? "bin\\hasinit.cmd" : "sh bin/hasinit.sh")
+            + " conf\n";
+
+    private static final String LEGAL_COMMANDS = "Available commands are: "
+            + "\n"
+            + "start_kdc, start\n"
+            + "                         Start kdc\n"
+            + "init_kdc, init\n"
+            + "                         Init kdc\n";
+
+    public static void main(String[] args) {
+        if (args.length < 1) {
+            System.err.println(USAGE);
+            System.exit(1);
+        }
+        String confDirPath = args[0];
+        File confFile = new File(confDirPath, "admin.conf");
+        HasConfig hasConfig;
+        try {
+            hasConfig = HasUtil.getHasConfig(confFile);
+        } catch (HasException e) {
+            System.err.println(e.getMessage());
+            return;
+        }
+
+        System.out.println(LEGAL_COMMANDS);
+        System.out.println("enter \"<cmd> [?][-help]\" to get cmd help.");
+        Scanner scanner = new Scanner(System.in, "UTF-8");
+        System.out.print(PROMPT + ": ");
+        String input = scanner.nextLine();
+
+        HasInitClient hasInitClient = new HasInitClient(hasConfig, new File(confDirPath));
+        while (!(input.equals("quit") || input.equals("exit") || input.equals("q"))) {
+            try {
+                execute(hasInitClient, input);
+            } catch (KrbException e) {
+                System.err.println(e.getMessage());
+            }
+            System.out.print(PROMPT + ": ");
+            input = scanner.nextLine();
+        }
+    }
+
+    private static void execute(HasInitClient hasInitClient, String input) throws KrbException {
+        input = input.trim();
+        if (input.startsWith("cmd")) {
+            System.out.println(LEGAL_COMMANDS);
+            return;
+        }
+        String[] items = input.split("\\s+");
+        String cmd = items[0];
+
+        InitCmd executor;
+        if (cmd.equals("start_kdc")
+            || cmd.equals("start")) {
+            executor = new StartKdcCmd(hasInitClient);
+        } else if (cmd.equals("init_kdc")
+            || cmd.equals("init")) {
+            executor = new InitKdcCmd(hasInitClient);
+        } else {
+            System.out.println(LEGAL_COMMANDS);
+            return;
+        }
+        executor.execute(items);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/InitCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/InitCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/InitCmd.java
new file mode 100644
index 0000000..63446d7
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/InitCmd.java
@@ -0,0 +1,42 @@
+/**
+ *  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.tool.init.cmd;
+
+import org.apache.kerby.has.client.HasInitClient;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+public abstract class InitCmd {
+
+    private HasInitClient client;
+
+    public InitCmd(HasInitClient client) {
+        this.client = client;
+    }
+
+    protected HasInitClient getClient() {
+        return client;
+    }
+
+    /**
+     * Execute the kdc init cmd.
+     * @param input Input cmd to execute
+     */
+    public abstract void execute(String[] input) throws KrbException;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/InitKdcCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/InitKdcCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/InitKdcCmd.java
new file mode 100644
index 0000000..d9ad062
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/InitKdcCmd.java
@@ -0,0 +1,85 @@
+/**
+ *  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.tool.init.cmd;
+
+import org.apache.kerby.has.client.HasInitClient;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Remote init kdc cmd
+ */
+public class InitKdcCmd extends InitCmd {
+
+    public static final String USAGE = "Usage: init_kdc [-p] [path]\n"
+        + "\tExample:\n"
+        + "\t\tinit_kdc\n";
+
+    public InitKdcCmd(HasInitClient client) {
+        super(client);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        if (items.length >= 2 && (items[1].startsWith("?") || items[1].startsWith("-help"))) {
+                System.out.println(USAGE);
+            return;
+        }
+        File path = getClient().getConfDir();
+        if (items.length >= 3 && items[1].startsWith("-p")) {
+            path = new File(items[2]);
+            if (!path.exists() && !path.mkdirs()) {
+                System.err.println("Cannot create file : " + items[2]);
+                return;
+            }
+        }
+        File adminKeytab = new File(path, "admin.keytab");
+
+        HasInitClient client = getClient();
+        InputStream content = client.initKdc();
+
+        if (content == null) {
+            return;
+        }
+
+        try (FileOutputStream fos = new FileOutputStream(adminKeytab)) {
+            byte[] buffer = new byte[4 * 1024];
+            int read;
+            while ((read = content.read(buffer)) > 0) {
+                fos.write(buffer, 0, read);
+            }
+            fos.close();
+            content.close();
+        } catch (FileNotFoundException e) {
+            System.err.println("the admin keytab file not found. " + e.getMessage());
+        } catch (IOException e) {
+            System.err.println("Errors occurred when getting the admin.keytab. " + e.getMessage());
+        }
+
+        System.out.println("admin.keytab has saved in : " + adminKeytab.getAbsolutePath()
+            + ",\nplease safely save it to use kadmin.");
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/488f15a6/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/StartKdcCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/StartKdcCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/StartKdcCmd.java
new file mode 100644
index 0000000..36405b2
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/init/cmd/StartKdcCmd.java
@@ -0,0 +1,52 @@
+/**
+ *  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.tool.init.cmd;
+
+import org.apache.kerby.has.client.HasInitClient;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+/**
+ * Remote start kdc cmd
+ */
+public class StartKdcCmd extends InitCmd {
+
+    public static final String USAGE = "Usage: start_kdc\n"
+        + "\tExample:\n"
+        + "\t\tstart\n";
+
+    public StartKdcCmd(HasInitClient client) {
+        super(client);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        if (items.length >= 2 && (items[1].startsWith("?") || items[1].startsWith("-help"))) {
+                System.out.println(USAGE);
+                return;
+        }
+
+        if (items.length != 1) {
+            System.err.println(USAGE);
+            return;
+        }
+        HasInitClient client = getClient();
+        client.startKdc();
+    }
+}


Mime
View raw message