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 2018/04/20 06:15:29 UTC

directory-kerby git commit: DIRKRB-709 Add principals and export keytabs by host roles in remote admin tool.

Repository: directory-kerby
Updated Branches:
  refs/heads/trunk f48eae33c -> c4a3a864b


DIRKRB-709 Add principals and export keytabs by host roles in remote admin tool.


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

Branch: refs/heads/trunk
Commit: c4a3a864b765beedcdc6b9c88d98f62265161337
Parents: f48eae3
Author: plusplusjiajia <ji...@intel.com>
Authored: Fri Apr 20 14:12:48 2018 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Fri Apr 20 14:12:48 2018 +0800

----------------------------------------------------------------------
 .../kerby/has/client/HasAuthAdminClient.java    | 197 ++++++++++++++++++-
 .../org/apache/kerby/has/common/Hadmin.java     |   3 +-
 .../kerby/has/server/admin/LocalHadmin.java     |  18 +-
 .../kerby/has/server/web/rest/HadminApi.java    |  74 ++++++-
 .../kerberos/tool/admin/AdminRemoteTool.java    |  32 ++-
 .../tool/admin/cmd/AddPrincipalsRemoteCmd.java  |  82 ++++++++
 .../kerberos/tool/admin/cmd/AdminRemoteCmd.java |   4 +-
 .../tool/admin/cmd/DisableConfRemoteCmd.java    |  48 +++++
 .../tool/admin/cmd/EnableConfRemoteCmd.java     |  49 +++++
 .../tool/admin/cmd/ExportKeytabsRemoteCmd.java  |  57 ++++++
 .../tool/admin/cmd/GetHostRolesRemoteCmd.java   |  72 +++++++
 11 files changed, 613 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/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 e9a7dc9..04b356d 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
@@ -21,6 +21,7 @@ package org.apache.kerby.has.client;
 
 import org.apache.kerby.KOptions;
 import org.apache.kerby.has.common.HasConfig;
+import org.apache.kerby.has.common.HasException;
 import org.apache.kerby.has.common.ssl.SSLFactory;
 import org.apache.kerby.has.common.util.URLConnectionFactory;
 import org.apache.kerby.kerberos.kerb.KrbException;
@@ -36,6 +37,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.ProtocolException;
@@ -97,10 +99,18 @@ public class HasAuthAdminClient implements Kadmin {
     }
 
     private String getKadminBaseURL() {
+        return getBaseUrl("kadmin");
+    }
+
+    private String getHadminBaseURL() {
+        return getBaseUrl("hadmin");
+    }
+
+    private String getBaseUrl(String input) {
         String url = null;
         if (hasConfig.getHttpsPort() != null && hasConfig.getHttpsHost() != null) {
             url = "https://" + hasConfig.getHttpsHost() + ":" + hasConfig.getHttpsPort()
-                + "/has/v1/kadmin/";
+                + "/has/v1/" + input + "/";
         }
         if (url == null) {
             throw new RuntimeException("Please set the https address and port.");
@@ -295,7 +305,7 @@ public class HasAuthAdminClient implements Kadmin {
             LOG.error("IO error occurred." + e.getMessage());
             throw new KrbException("IO error occurred.", e);
         }
-        return getPrincsList(response);
+        return stringtoList(response);
     }
 
     @Override
@@ -333,22 +343,22 @@ public class HasAuthAdminClient implements Kadmin {
         } catch (IOException e) {
             throw new KrbException("IO error occurred.", e);
         }
-        return getPrincsList(response);
+        return stringtoList(response);
     }
 
     /**
-     * Change principals JSON string to a List.
+     * Change JSON string to a List.
      *
-     * @param princs principals JSON string which like
+     * @param result principals JSON string which like
      *               "["HTTP\/host1@HADOOP.COM","HTTP\/host2@HADOOP.COM"]"
      * @return principalLists.
      */
-    private List<String> getPrincsList(String princs) throws KrbException {
+    private List<String> stringtoList(String result) throws KrbException {
         List<String> principalLists = new ArrayList<>();
         try {
-            JSONArray principals = new JSONArray(princs);
-            for (int i = 0; i < principals.length(); i++) {
-                principalLists.add("\t" + principals.getString(i));
+            JSONArray jsonArray = new JSONArray(result);
+            for (int i = 0; i < jsonArray.length(); i++) {
+                principalLists.add("\t" + jsonArray.getString(i));
             }
         } catch (JSONException e) {
             throw new KrbException("JSON Exception occurred. ", e);
@@ -498,4 +508,173 @@ public class HasAuthAdminClient implements Kadmin {
         }
         return data.toString();
     }
+
+    public List<String> addPrincipalsByRole(String hostRoles) throws KrbException {
+        HttpURLConnection httpConn;
+
+        URL url;
+        try {
+            url = new URL(getHadminBaseURL() + "addprincipalsbyrole");
+        } catch (MalformedURLException e) {
+            throw new KrbException(e.getMessage());
+        }
+
+        httpConn = createConnection(url, "POST");
+
+        httpConn.setRequestProperty("Content-Type",
+                "application/json; charset=UTF-8");
+        try {
+            httpConn.setRequestMethod("PUT");
+        } catch (ProtocolException e) {
+            throw new KrbException(e.getMessage());
+        }
+        httpConn.setDoOutput(true);
+        httpConn.setDoInput(true);
+        String response;
+        try {
+            httpConn.connect();
+            OutputStream out = httpConn.getOutputStream();
+            out.write(hostRoles.toString().getBytes());
+            out.flush();
+            out.close();
+            if (httpConn.getResponseCode() == 200) {
+                response = getResponse(httpConn);
+            } else {
+                throw new KrbException(getResponse(httpConn));
+            }
+        } catch (Exception e) {
+            throw new KrbException(e.getMessage());
+        }
+        return stringtoList(response);
+    }
+
+    public void setEnableOfConf(String isEnable) throws HasException {
+        HttpURLConnection httpConn;
+
+        URL url;
+        try {
+            url = new URL(getHadminBaseURL() + "setconf?isEnable=" + isEnable);
+        } catch (MalformedURLException e) {
+            throw new HasException(e);
+        }
+
+        httpConn = createConnection(url, "PUT");
+
+        httpConn.setRequestProperty("Content-Type",
+                "application/json; charset=UTF-8");
+        try {
+            httpConn.setRequestMethod("PUT");
+        } catch (ProtocolException e) {
+            throw new HasException(e);
+        }
+        try {
+            httpConn.setDoOutput(true);
+            httpConn.setDoInput(true);
+            httpConn.connect();
+            InputStream inputStream = httpConn.getResponseCode() == 200
+                    ? httpConn.getInputStream() : httpConn.getErrorStream();
+            BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(inputStream));
+            String s;
+            StringBuilder result = new StringBuilder();
+            while ((s = reader.readLine()) != null) {
+                result.append(s);
+            }
+            if (httpConn.getResponseCode() == 200) {
+                System.out.println(result);
+            } else {
+                System.err.println(result);
+            }
+        } catch (Exception e) {
+            LOG.error("Fail to connect to server. " + e);
+            throw new HasException(e);
+        }
+    }
+
+    public File getKeytabByHostAndRole(String host, String role) throws HasException {
+        String keytabName = host + ".zip";
+        HttpURLConnection httpConn;
+        String request = getHadminBaseURL() + "exportKeytabsbyrole?host=" + host;
+        if (!role.equals("")) {
+            request = request + "&role=" + role;
+            keytabName = role + "-" + host + ".keytab";
+        }
+
+        URL url;
+        try {
+            url = new URL(request);
+        } catch (MalformedURLException e) {
+            throw new HasException(e);
+        }
+
+        httpConn = createConnection(url, "GET");
+
+        httpConn.setRequestProperty("Content-Type",
+            "application/json; charset=UTF-8");
+        try {
+            httpConn.setRequestMethod("GET");
+        } catch (ProtocolException e) {
+            throw new HasException(e);
+        }
+        httpConn.setDoOutput(true);
+        httpConn.setDoInput(true);
+        try {
+            httpConn.connect();
+
+            if (httpConn.getResponseCode() != 200) {
+                System.err.println("Error : connection denied.");
+                return null;
+            }
+            FileOutputStream fos = new FileOutputStream(new File(keytabName));
+            InputStream in = httpConn.getInputStream();
+            byte[] buffer = new byte[4 * 1024];
+            int read;
+            while ((read = in.read(buffer)) > 0) {
+                fos.write(buffer, 0, read);
+            }
+            fos.close();
+            in.close();
+        } catch (IOException e) {
+            throw new HasException(e);
+        }
+        System.out.println("Accept keytab file \"" + keytabName + "\" from server.");
+
+        return new File(keytabName);
+    }
+
+    public String getHostRoles() throws KrbException {
+        HttpURLConnection httpConn;
+
+        URL url;
+        try {
+            url = new URL(getHadminBaseURL() + "hostroles");
+        } catch (MalformedURLException e) {
+            throw new KrbException("Failed to create a URL object.", e);
+        }
+
+        httpConn = createConnection(url, "GET");
+
+        httpConn.setRequestProperty("Content-Type",
+            "application/json; charset=UTF-8");
+        try {
+            httpConn.setRequestMethod("GET");
+        } catch (ProtocolException e) {
+            throw new KrbException("Failed to set the method for URL request.", e);
+        }
+        String response;
+        try {
+            httpConn.setDoInput(true);
+            httpConn.connect();
+
+            if (httpConn.getResponseCode() == 200) {
+                response = getResponse(httpConn);
+            } else {
+                throw new KrbException(getResponse(httpConn));
+            }
+        } catch (IOException e) {
+            LOG.error("IO error occurred." + e.getMessage());
+            throw new KrbException("IO error occurred.", e);
+        }
+        return response;
+    }
 }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/has-project/has-common/src/main/java/org/apache/kerby/has/common/Hadmin.java
----------------------------------------------------------------------
diff --git a/has-project/has-common/src/main/java/org/apache/kerby/has/common/Hadmin.java b/has-project/has-common/src/main/java/org/apache/kerby/has/common/Hadmin.java
index 882b10f..bff7760 100644
--- a/has-project/has-common/src/main/java/org/apache/kerby/has/common/Hadmin.java
+++ b/has-project/has-common/src/main/java/org/apache/kerby/has/common/Hadmin.java
@@ -20,6 +20,7 @@
 package org.apache.kerby.has.common;
 
 import java.io.File;
+import java.util.List;
 
 /**
  * Server side admin facilities from remote, similar to MIT kadmin remote mode.
@@ -27,7 +28,7 @@ import java.io.File;
 public interface Hadmin {
 
 
-    String addPrincByRole(String host, String role) throws HasException;
+    List<String> addPrincByRole(String host, String role) throws HasException;
 
     File getKeytabByHostAndRole(String host, String role) throws HasException;
 

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/has-project/has-server/src/main/java/org/apache/kerby/has/server/admin/LocalHadmin.java
----------------------------------------------------------------------
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/admin/LocalHadmin.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/admin/LocalHadmin.java
index 8f32eeb..0ece5f8 100644
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/admin/LocalHadmin.java
+++ b/has-project/has-server/src/main/java/org/apache/kerby/has/server/admin/LocalHadmin.java
@@ -35,6 +35,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
 public class LocalHadmin implements Hadmin {
     public static final Logger LOG = LoggerFactory.getLogger(LocalHadmin.class);
@@ -73,22 +75,24 @@ public class LocalHadmin implements Hadmin {
     }
 
     @Override
-    public String addPrincByRole(String host, String role) throws HasException {
-        String result = "";
+    public List<String> addPrincByRole(String host, String role) throws HasException {
+        List<String> result = new ArrayList<>();
         String realm = "/" + host + "@" + kadmin.getKdcConfig().getKdcRealm();
         String[] princs = HostRoleType.valueOf(role).getPrincs();
         if (princs == null) {
             LOG.error("Cannot find the role of : " + role);
-            return "Cannot find the role of : " + role;
+            result.add("Cannot find the role of : " + role);
+            return result;
         }
         for (String princ : princs) {
             try {
                 kadmin.addPrincipal(princ + realm);
-                LOG.info("Success to add princ :" + princ + realm);
-                result = result + "Success to add princ :" + princ + realm + "\n";
+                LOG.info("Success to add princ: " + princ + realm);
+                result.add("Success to add princ: " + princ + realm);
             } catch (KrbException e) {
-                LOG.info(e.getMessage());
-                result = e.getMessage() + "\n";
+                String message = e.getMessage();
+                LOG.info(message);
+                result.add(message);
             }
         }
         return result;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/HadminApi.java
----------------------------------------------------------------------
diff --git a/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/HadminApi.java b/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/HadminApi.java
index c8c21f8..f1ba87c 100644
--- a/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/HadminApi.java
+++ b/has-project/has-server/src/main/java/org/apache/kerby/has/server/web/rest/HadminApi.java
@@ -17,7 +17,9 @@
  */
 package org.apache.kerby.has.server.web.rest;
 
+import org.apache.hadoop.http.JettyUtils;
 import org.apache.kerby.has.common.HasException;
+import org.apache.kerby.has.common.util.HasUtil;
 import org.apache.kerby.has.server.HasServer;
 import org.apache.kerby.has.server.admin.LocalHadmin;
 import org.apache.kerby.has.server.web.HostRoleType;
@@ -94,7 +96,7 @@ public class HadminApi {
             } catch (KrbException e) {
                 WebServer.LOG.info("Failed to create local hadmin." + e.getMessage());
             }
-            StringBuilder msg = new StringBuilder();
+            JSONArray results = new JSONArray();
             try {
                 StringBuilder data = new StringBuilder();
                 BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
@@ -108,10 +110,13 @@ public class HadminApi {
                     JSONObject host = (JSONObject) hostArray.get(i);
                     String[] roles = host.getString("hostRoles").split(",");
                     for (String role : roles) {
-                        msg.append(hasAdmin.addPrincByRole(host.getString("name"), role.toUpperCase()));
+                        List<String> strs = hasAdmin.addPrincByRole(host.getString("name"), role.toUpperCase());
+                        for (String str : strs) {
+                            results.put(str);
+                        }
                     }
                 }
-                return Response.ok(msg).build();
+                return Response.ok(results.toString()).build();
             } catch (Exception e) {
                 WebServer.LOG.error("Failed to create principals,because : " + e.getMessage());
                 String error = "Failed to create principals,because : " + e.getMessage();
@@ -209,4 +214,67 @@ public class HadminApi {
         }
         return Response.status(Response.Status.FORBIDDEN).entity("HTTPS required.\n").build();
     }
+
+    @GET
+    @Path("/hostroles")
+    @Produces(MediaType.APPLICATION_JSON + ";" + JettyUtils.UTF_8)
+    public Response getRoles() {
+        if (httpRequest.isSecure()) {
+            JSONArray result = new JSONArray();
+            try {
+                for (HostRoleType role : HostRoleType.values()) {
+                    JSONObject json = new JSONObject();
+                    json.put("HostRole", role.getName());
+                    JSONArray jsa = new JSONArray();
+                    String[] princs = role.getPrincs();
+                    for (String princ : princs) {
+                        jsa.put(princ);
+                    }
+                    json.put("PrincipalNames", jsa);
+                    result.put(json);
+                }
+                return Response.ok(result.toString() + "\n").build();
+            } catch (Exception e) {
+                String msg = "Failed to get host roles." + 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();
+    }
+
+    @PUT
+    @Path("/setconf")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response setConf(@QueryParam("isEnable") String isEnable) {
+        if (httpRequest.isSecure()) {
+            WebServer.LOG.info("Request to admin/setconf.");
+            final HasServer hasServer = WebServer.getHasServerFromContext(
+                context);
+            File hasConf = new File(hasServer.getConfDir(), "has-server.conf");
+            if (!hasConf.exists()) {
+                WebServer.LOG.error("has-server.conf is not exists.");
+                return Response.serverError().entity("has-server.conf is not exists.")
+                    .build();
+            }
+            String result = "";
+            if (isEnable.equals("true")) {
+                result = "enable";
+            } else if (isEnable.equals("false")) {
+                result = "disable";
+            } else {
+                WebServer.LOG.error("Value of isEnable is error.");
+                return Response.serverError().entity("Value of isEnable is error.")
+                    .build();
+            }
+            try {
+                HasUtil.setEnableConf(hasConf, isEnable);
+            } catch (Exception e) {
+                WebServer.LOG.error(e.getMessage());
+                return Response.serverError().entity(e.getMessage()).build();
+            }
+            return Response.ok("Set conf to " + result).build();
+        }
+        return Response.status(Response.Status.FORBIDDEN).entity("HTTPS required.\n").build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/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
index fc2356c..abf9f25 100644
--- 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
@@ -25,8 +25,13 @@ 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.AddPrincipalsRemoteCmd;
 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.DisableConfRemoteCmd;
+import org.apache.kerby.kerberos.tool.admin.cmd.EnableConfRemoteCmd;
+import org.apache.kerby.kerberos.tool.admin.cmd.ExportKeytabsRemoteCmd;
+import org.apache.kerby.kerberos.tool.admin.cmd.GetHostRolesRemoteCmd;
 import org.apache.kerby.kerberos.tool.admin.cmd.ListPrincipalsRemoteCmd;
 import org.apache.kerby.kerberos.tool.admin.cmd.RenamePrincipalRemoteCmd;
 import org.apache.kerby.util.OSUtil;
@@ -55,7 +60,17 @@ public class AdminRemoteTool {
         + "rename_principal, renprinc\n"
         + "                         Rename principal\n"
         + "list_principals, listprincs\n"
-        + "                         List principals\n";
+        + "                         List principals\n"
+        + "get_hostroles, hostroles\n"
+        + "                         Get hostRoles\n"
+        + "export_keytabs, expkeytabs\n"
+        + "                         Export keytabs\n"
+        + "add_principals, addprincs\n"
+        + "                         Add principals\n"
+        + "enable_configure, enable\n"
+        + "                         Enable configure\n"
+        + "disable_configure, disable\n"
+        + "                         Disable configure\n";
 
     public static void main(String[] args) {
 
@@ -122,6 +137,21 @@ public class AdminRemoteTool {
         } else if (cmd.equals("list_principals")
             || cmd.equals("listprincs")) {
             executor = new ListPrincipalsRemoteCmd(hasAuthAdminClient);
+        } else if (cmd.equals("get_hostroles")
+            || cmd.equals("hostroles")) {
+            executor = new GetHostRolesRemoteCmd(hasAuthAdminClient);
+        } else if (cmd.equals("add_principals")
+            || cmd.equals("addprincs")) {
+            executor = new AddPrincipalsRemoteCmd(hasAuthAdminClient);
+        } else if (cmd.equals("export_keytabs")
+            || cmd.equals("expkeytabs")) {
+            executor = new ExportKeytabsRemoteCmd(hasAuthAdminClient);
+        } else if (cmd.equals("enable_configure")
+            || cmd.equals("enable")) {
+            executor = new EnableConfRemoteCmd(hasAuthAdminClient);
+        } else if (cmd.equals("disable_configure")
+            || cmd.equals("disable")) {
+            executor = new DisableConfRemoteCmd(hasAuthAdminClient);
         } else {
             System.out.println(LEGAL_COMMANDS);
             return;

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AddPrincipalsRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AddPrincipalsRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AddPrincipalsRemoteCmd.java
new file mode 100644
index 0000000..fd6cfa6
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/AddPrincipalsRemoteCmd.java
@@ -0,0 +1,82 @@
+/**
+ *  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.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+
+public class AddPrincipalsRemoteCmd extends AdminRemoteCmd {
+    private static final String USAGE = "\nUsage: add_principals [hostRoles-file]\n"
+            + "\t'hostRoles-file' is a file with a hostRoles json string like:\n"
+            + "\t\t{HOSTS: [ {\"name\":\"host1\",\"hostRoles\":\"HDFS\"}, "
+            + "{\"name\":\"host2\",\"hostRoles\":\"HDFS,HBASE\"} ] }\n"
+            + "\tExample:\n"
+            + "\t\tadd_principals hostroles.txt\n";
+
+    public AddPrincipalsRemoteCmd(HasAuthAdminClient authHadmin) {
+        super(authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        //String param = items[0];
+        if (items.length != 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        File hostRoles = new File(items[1]);
+        if (!hostRoles.exists()) {
+            System.err.println("HostRoles file is not exists.");
+            return;
+        }
+
+        HasAuthAdminClient client = getAuthAdminClient();
+
+        BufferedReader reader;
+        try {
+            reader = new BufferedReader(new FileReader(hostRoles));
+        } catch (FileNotFoundException e) {
+            throw new KrbException("File not exist", e);
+        }
+        StringBuilder sb = new StringBuilder();
+        String tempString;
+        try {
+            while ((tempString = reader.readLine()) != null) {
+                sb.append(tempString);
+            }
+        } catch (IOException e) {
+            throw new KrbException("Errors occurred when read line. ", e);
+        }
+        List<String> results = client.addPrincipalsByRole(sb.toString());
+        if (results != null) {
+            for (int i = 0; i < results.size(); i++) {
+                System.out.println(results.get(i));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/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
index b5ccee4..b74f69f 100644
--- 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
@@ -36,7 +36,7 @@ public abstract class AdminRemoteCmd {
 
     /**
      * Execute the admin cmd.
-     * @param input Input cmd to execute
+     * @param items Input cmd to execute
      */
-    public abstract void execute(String[] input) throws KrbException;
+    public abstract void execute(String[] items) throws KrbException;
 }

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/DisableConfRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/DisableConfRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/DisableConfRemoteCmd.java
new file mode 100644
index 0000000..c152ad2
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/DisableConfRemoteCmd.java
@@ -0,0 +1,48 @@
+/**
+ *  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.has.common.HasException;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+/**
+ * Remote add principal cmd
+ */
+public class DisableConfRemoteCmd extends AdminRemoteCmd {
+
+    public static final String USAGE = "Usage: disable_configure\n"
+            + "\tExample:\n"
+            + "\t\tdisable\n";
+
+    public DisableConfRemoteCmd(HasAuthAdminClient authHadmin) {
+        super(authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        HasAuthAdminClient client = getAuthAdminClient();
+        try {
+            client.setEnableOfConf("false");
+        } catch (HasException e) {
+            throw new KrbException(e.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/EnableConfRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/EnableConfRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/EnableConfRemoteCmd.java
new file mode 100644
index 0000000..28011a8
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/EnableConfRemoteCmd.java
@@ -0,0 +1,49 @@
+/**
+ *  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.has.common.HasException;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+/**
+ * Remote add principal cmd
+ */
+public class EnableConfRemoteCmd extends AdminRemoteCmd {
+
+    public static final String USAGE = "Usage: enable_configure\n"
+            + "\tExample:\n"
+            + "\t\tenable\n";
+
+    public EnableConfRemoteCmd(HasAuthAdminClient authHadmin) {
+        super(authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+
+        HasAuthAdminClient client = getAuthAdminClient();
+        try {
+            client.setEnableOfConf("true");
+        } catch (HasException e) {
+            throw new KrbException(e.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/ExportKeytabsRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/ExportKeytabsRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/ExportKeytabsRemoteCmd.java
new file mode 100644
index 0000000..52513ca
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/ExportKeytabsRemoteCmd.java
@@ -0,0 +1,57 @@
+/**
+ *  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.has.common.HasException;
+import org.apache.kerby.kerberos.kerb.KrbException;
+
+public class ExportKeytabsRemoteCmd extends AdminRemoteCmd {
+    private static final String USAGE = "\nUsage: export_keytabs <host> [role]\n"
+            + "\tExample:\n"
+            + "\t\texport_keytabs host1 HDFS\n";
+
+    public ExportKeytabsRemoteCmd(HasAuthAdminClient authHadmin) {
+        super(authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        //TODO add save path option
+        //String param = items[0];
+        if (items.length < 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        HasAuthAdminClient client = getAuthAdminClient();
+
+        String host = items[1];
+        String role = "";
+        if (items.length >= 3) {
+            role = items[2];
+        }
+        try {
+            client.getKeytabByHostAndRole(host, role);
+        } catch (HasException e) {
+            throw new KrbException(e.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/c4a3a864/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/GetHostRolesRemoteCmd.java
----------------------------------------------------------------------
diff --git a/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/GetHostRolesRemoteCmd.java b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/GetHostRolesRemoteCmd.java
new file mode 100644
index 0000000..cc01e63
--- /dev/null
+++ b/kerby-tool/has-tool/src/main/java/org/apache/kerby/kerberos/tool/admin/cmd/GetHostRolesRemoteCmd.java
@@ -0,0 +1,72 @@
+/**
+ *  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 org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+
+public class GetHostRolesRemoteCmd extends AdminRemoteCmd {
+    private static final String USAGE = "Usage: get_hostroles\n"
+            + "\tExample:\n"
+            + "\t\tget_hostroles\n";
+
+    public GetHostRolesRemoteCmd(HasAuthAdminClient authHadmin) {
+        super(authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws KrbException {
+        if (items.length > 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        HasAuthAdminClient hasAdminClient = getAuthAdminClient();
+        String result = hasAdminClient.getHostRoles();
+
+        if (result != null) {
+            try {
+                JSONArray hostRoles = new JSONArray(result);
+                for (int i = 0; i < hostRoles.length(); i++) {
+                    JSONObject hostRole = hostRoles.getJSONObject(i);
+                    System.out.print("\tHostRole: " + hostRole.getString("HostRole")
+                            + ", PrincipalNames: ");
+                    JSONArray principalNames = hostRole.getJSONArray("PrincipalNames");
+                    for (int j = 0; j < principalNames.length(); j++) {
+                        System.out.print(principalNames.getString(j));
+                        if (j == principalNames.length() - 1) {
+                            System.out.println();
+                        } else {
+                            System.out.print(", ");
+                        }
+                    }
+                }
+            } catch (JSONException e) {
+                throw new KrbException("Errors occurred when getting the host roles.", e);
+            }
+        } else {
+            throw new KrbException("Could not get hostRoles.");
+        }
+    }
+
+}