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 2017/11/28 03:04:04 UTC

[03/15] directory-kerby git commit: Change the Maven groupId in HAS folder to org.apache.kerby.

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

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/HasSetPluginCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/HasSetPluginCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/HasSetPluginCmd.java
deleted file mode 100644
index 457cf50..0000000
--- a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/HasSetPluginCmd.java
+++ /dev/null
@@ -1,53 +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.hadoop.has.tool.client.kdcinit.cmd;
-
-import org.apache.hadoop.has.client.HasAdminClient;
-import org.apache.kerby.kerberos.kerb.KrbException;
-
-/**
- * Remote set plugin cmd
- */
-public class HasSetPluginCmd extends KdcInitCmd {
-
-    public static final String USAGE = "Usage: set_plugin <plugin>\n"
-        + "\tExample:\n"
-        + "\t\tset_plugin RAM\n";
-
-    public HasSetPluginCmd(HasAdminClient hadmin) {
-        super(hadmin);
-    }
-
-    @Override
-    public void execute(String[] items) throws KrbException {
-        if (items.length >= 2) {
-            if (items[1].startsWith("?") || items[1].startsWith("-help")) {
-                System.out.println(USAGE);
-                return;
-            }
-        } else {
-            System.err.println(USAGE);
-            return;
-        }
-
-        HasAdminClient hasAdminClient = getHadmin();
-        hasAdminClient.setPlugin(items[1]);
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/HasStartKdcCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/HasStartKdcCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/HasStartKdcCmd.java
deleted file mode 100644
index 6511e0a..0000000
--- a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/HasStartKdcCmd.java
+++ /dev/null
@@ -1,49 +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.hadoop.has.tool.client.kdcinit.cmd;
-
-import org.apache.hadoop.has.client.HasAdminClient;
-import org.apache.kerby.kerberos.kerb.KrbException;
-
-/**
- * Remote start kdc cmd
- */
-public class HasStartKdcCmd extends KdcInitCmd {
-
-    public static final String USAGE = "Usage: start_kdc\n"
-        + "\tExample:\n"
-        + "\t\tstart\n";
-
-    public HasStartKdcCmd(HasAdminClient hadmin) {
-        super(hadmin);
-    }
-
-    @Override
-    public void execute(String[] items) throws KrbException {
-        if (items.length >= 2) {
-            if (items[1].startsWith("?") || items[1].startsWith("-help")) {
-                System.out.println(USAGE);
-                return;
-            }
-        }
-        HasAdminClient hasAdminClient = getHadmin();
-        hasAdminClient.startKdc();
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/KdcInitCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/KdcInitCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/KdcInitCmd.java
deleted file mode 100644
index a75f702..0000000
--- a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kdcinit/cmd/KdcInitCmd.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.hadoop.has.tool.client.kdcinit.cmd;
-
-import org.apache.hadoop.has.client.HasAdminClient;
-import org.apache.kerby.kerberos.kerb.KrbException;
-
-public abstract class KdcInitCmd {
-
-    private HasAdminClient hadmin;
-
-    public KdcInitCmd(HasAdminClient hadmin) {
-        this.hadmin = hadmin;
-    }
-
-    protected HasAdminClient getHadmin() {
-        return hadmin;
-    }
-
-    /**
-     * 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/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kinit/KinitOption.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kinit/KinitOption.java b/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kinit/KinitOption.java
deleted file mode 100644
index 0e29085..0000000
--- a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kinit/KinitOption.java
+++ /dev/null
@@ -1,88 +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.hadoop.has.tool.client.kinit;
-
-import org.apache.kerby.KOption;
-import org.apache.kerby.KOptionInfo;
-import org.apache.kerby.KOptionType;
-import org.apache.kerby.kerberos.kerb.client.KrbOptionGroup;
-
-public enum KinitOption implements KOption {
-    NONE(null),
-
-    CLIENT_PRINCIPAL(new KOptionInfo("client-principal", "Client principal",
-        KrbOptionGroup.KRB, KOptionType.STR)),
-    LIFE_TIME(new KOptionInfo("-l", "lifetime",
-        KrbOptionGroup.KRB, KOptionType.DURATION)),
-    START_TIME(new KOptionInfo("-s", "start time",
-        KrbOptionGroup.KRB, KOptionType.DURATION)),
-    RENEWABLE_LIFE(new KOptionInfo("-r", "renewable lifetime",
-        KrbOptionGroup.KRB, KOptionType.DURATION)),
-    FORWARDABLE(new KOptionInfo("-f", "forwardable",
-        KrbOptionGroup.KDC_FLAGS)),
-    NOT_FORWARDABLE(new KOptionInfo("-F", "not forwardable",
-        KrbOptionGroup.KDC_FLAGS)),
-    PROXIABLE(new KOptionInfo("-p", "proxiable",
-        KrbOptionGroup.KDC_FLAGS)),
-    NOT_PROXIABLE(new KOptionInfo("-P", "not proxiable",
-        KrbOptionGroup.KDC_FLAGS)),
-    RENEW(new KOptionInfo("-R", "renew",
-        KrbOptionGroup.KDC_FLAGS)),
-    USE_PASSWD(new KOptionInfo("using-password", "using password",
-        KrbOptionGroup.KRB)),
-    USER_PASSWD(new KOptionInfo("user-passwd", "User plain password",
-        KrbOptionGroup.KRB)),
-    USE_KEYTAB(new KOptionInfo("-k", "use keytab",
-        KrbOptionGroup.KRB)),
-    USE_DFT_KEYTAB(new KOptionInfo("-i", "use default client keytab (with -k)",
-        KrbOptionGroup.KRB)),
-    KEYTAB_FILE(new KOptionInfo("-t", "filename of keytab to use",
-        KrbOptionGroup.KRB, KOptionType.FILE)),
-    KRB5_CACHE(new KOptionInfo("-c", "Kerberos 5 cache name",
-        KrbOptionGroup.KRB, KOptionType.STR)),
-    SERVICE(new KOptionInfo("-S", "service",
-        KrbOptionGroup.KRB, KOptionType.STR)),
-
-    CONF_DIR(new KOptionInfo("-conf", "conf dir", KrbOptionGroup.KRB, KOptionType.DIR));
-
-    private final KOptionInfo optionInfo;
-
-    KinitOption(KOptionInfo optionInfo) {
-        this.optionInfo = optionInfo;
-    }
-
-    @Override
-    public KOptionInfo getOptionInfo() {
-        return optionInfo;
-    }
-
-    public static KinitOption fromName(String name) {
-        if (name != null) {
-            for (KinitOption ko : values()) {
-                if (ko.optionInfo != null
-                        && ko.optionInfo.getName().equals(name)) {
-                    return ko;
-                }
-            }
-        }
-        return NONE;
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kinit/KinitTool.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kinit/KinitTool.java b/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kinit/KinitTool.java
deleted file mode 100644
index a061266..0000000
--- a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/kinit/KinitTool.java
+++ /dev/null
@@ -1,384 +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.hadoop.has.tool.client.kinit;
-
-import org.apache.kerby.KOption;
-import org.apache.kerby.KOptionGroup;
-import org.apache.kerby.KOptionInfo;
-import org.apache.kerby.KOptionType;
-import org.apache.kerby.KOptions;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.client.KrbClient;
-import org.apache.kerby.kerberos.kerb.client.KrbKdcOption;
-import org.apache.kerby.kerberos.kerb.client.KrbOption;
-import org.apache.kerby.kerberos.kerb.client.KrbOptionGroup;
-import org.apache.kerby.kerberos.kerb.client.PkinitOption;
-import org.apache.kerby.kerberos.kerb.client.TokenOption;
-import org.apache.kerby.kerberos.kerb.type.ticket.SgtTicket;
-import org.apache.kerby.kerberos.kerb.type.ticket.TgtTicket;
-import org.apache.kerby.util.OSUtil;
-import org.apache.kerby.util.SysUtil;
-
-import java.io.Console;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Scanner;
-
-/**
- * kinit like tool
- *
- * Ref. MIT kinit command tool usage.
- */
-public class KinitTool {
-
-    private static final String USAGE = (OSUtil.isWindows()
-            ? "Usage: bin\\kinit.cmd" : "Usage: sh bin/kinit.sh")
-            + " <-conf conf_dir> [-V] [-l lifetime] [-s start_time]\n"
-            + "\t\t[-r renewable_life] [-f | -F] [-p | -P] -n [-a | -A] [-C] [-E]\n"
-            + "\t\t[-v] [-R] [-k [-i|-t keytab_file]] [-c cachename]\n"
-            + "\t\t[-S service_name] [-T ticket_armor_cache]\n"
-            + "\t\t[-X <attribute>[=<value>]] <principal>\n\n"
-            + "\tDESCRIPTION:\n"
-            + "\t\tkinit obtains and caches an initial ticket-granting ticket for principal.\n\n"
-            + "\tOPTIONS:\n"
-            + "\t\t-V verbose\n"
-            + "\t\t-l lifetime\n"
-            + "\t\t-s start time\n"
-            + "\t\t-r renewable lifetime\n"
-            + "\t\t-f forwardable\n"
-            + "\t\t-F not forwardable\n"
-            + "\t\t-p proxiable\n"
-            + "\t\t-P not proxiable\n"
-            + "\t\t-n anonymous\n"
-            + "\t\t-a include addresses\n"
-            + "\t\t-A do not include addresses\n"
-            + "\t\t-v validate\n"
-            + "\t\t-R renew\n"
-            + "\t\t-C canonicalize\n"
-            + "\t\t-E client is enterprise principal name\n"
-            + "\t\t-k use keytab\n"
-            + "\t\t-i use default client keytab (with -k)\n"
-            + "\t\t-t filename of keytab to use\n"
-            + "\t\t-c Kerberos 5 cache name\n"
-            + "\t\t-S service\n"
-            + "\t\t-T armor credential cache\n"
-            + "\t\t-X <attribute>[=<value>]\n"
-            + "\n";
-
-    private static void printUsage(String error) {
-        System.err.println(error + "\n");
-        System.err.println(USAGE);
-        System.exit(-1);
-    }
-
-    private static final String KVNO_USAGE = (OSUtil.isWindows()
-        ? "Usage: bin\\kinit.cmd" : "Usage: sh bin/kinit.sh")
-        + " <-conf conf_dir> <-c cachename> <-S service_name>\n\n"
-        + "\tDESCRIPTION:\n"
-        + "\t\tkinit obtains a service ticket for the specified principal and prints out the key version number.\n"
-        + "\n";
-
-    private static void printKvnoUsage(String error) {
-        System.err.println(error + "\n");
-        System.err.println(KVNO_USAGE);
-        System.exit(-1);
-    }
-
-    /**
-     * Get password for the input principal from console
-     */
-    private static String getPassword(String principal) {
-        Console console = System.console();
-        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.");
-            System.out.println("Password for " + principal + ":");
-            try (Scanner scanner = new Scanner(System.in, "UTF-8")) {
-                return scanner.nextLine().trim();
-            }
-        }
-        console.printf("Password for " + principal + ":");
-        char[] passwordChars = console.readPassword();
-        String password = new String(passwordChars).trim();
-        Arrays.fill(passwordChars, ' ');
-
-        return password;
-    }
-
-    private static void requestTicket(String principal, KOptions ktOptions) {
-        ktOptions.add(KinitOption.CLIENT_PRINCIPAL, principal);
-
-        File confDir = null;
-        if (ktOptions.contains(KinitOption.CONF_DIR)) {
-            confDir = ktOptions.getDirOption(KinitOption.CONF_DIR);
-        }
-
-        KrbClient krbClient = null;
-        try {
-            krbClient = getClient(confDir);
-        } catch (KrbException e) {
-            System.err.println("Create krbClient failed: " + e.getMessage());
-            System.exit(1);
-        }
-
-        if (ktOptions.contains(KinitOption.RENEW)) {
-            if (ktOptions.contains(KinitOption.KRB5_CACHE)) {
-                String ccName = ktOptions.getStringOption(KinitOption.KRB5_CACHE);
-                File ccFile = new File(ccName);
-
-                SgtTicket sgtTicket = null;
-                try {
-                    sgtTicket = krbClient.requestSgt(ccFile, null);
-                } catch (KrbException e) {
-                    System.err.println("kinit: " + e.getKrbErrorCode().getMessage());
-                }
-
-                try {
-                    krbClient.renewTicket(sgtTicket, ccFile);
-                } catch (KrbException e) {
-                    System.err.println("kinit: " + e.getKrbErrorCode().getMessage());
-                }
-
-                System.out.println("Successfully renewed.");
-            }
-            return;
-        }
-
-        if (ktOptions.contains(KinitOption.SERVICE) && ktOptions.contains(KinitOption.KRB5_CACHE)) {
-            String ccName = ktOptions.getStringOption(KinitOption.KRB5_CACHE);
-            File ccFile = new File(ccName);
-            if (ccFile.exists()) {
-                System.out.println("Use credential cache to request a service ticket.");
-                String servicePrincipal = ktOptions.getStringOption(KinitOption.SERVICE);
-                SgtTicket sgtTicket = null;
-                try {
-                    sgtTicket = krbClient.requestSgt(ccFile, servicePrincipal);
-                } catch (KrbException e) {
-                    System.err.println("Kinit: get service ticket failed: " + e.getMessage());
-                    System.exit(1);
-                }
-
-                try {
-                    krbClient.storeTicket(sgtTicket, ccFile);
-                } catch (KrbException e) {
-                    System.err.println("Kinit: store ticket failed: " + e.getMessage());
-                    System.exit(1);
-                }
-
-                System.out.println(sgtTicket.getEncKdcRepPart().getSname().getName() + ": knvo = "
-                    + sgtTicket.getTicket().getEncryptedEncPart().getKvno());
-                return;
-            }
-        }
-
-        if (!ktOptions.contains(KinitOption.USE_KEYTAB)) {
-            //If not request tickets by keytab than by password.
-            ktOptions.add(KinitOption.USE_PASSWD);
-            String password = getPassword(principal);
-            ktOptions.add(KinitOption.USER_PASSWD, password);
-        }
-
-        TgtTicket tgt = null;
-        try {
-            tgt = krbClient.requestTgt(convertOptions(ktOptions));
-        } catch (KrbException e) {
-            System.err.println("Authentication failed: " + e.getMessage());
-            System.exit(1);
-        }
-
-        File ccacheFile;
-        if (ktOptions.contains(KinitOption.KRB5_CACHE)) {
-            String ccacheName = ktOptions.getStringOption(KinitOption.KRB5_CACHE);
-            ccacheFile = new File(ccacheName);
-        } else {
-            String ccacheName = getCcacheName(krbClient);
-            ccacheFile = new File(ccacheName);
-        }
-
-        try {
-            krbClient.storeTicket(tgt, ccacheFile);
-        } catch (KrbException e) {
-            System.err.println("Store ticket failed: " + e.getMessage());
-            System.exit(1);
-        }
-
-        System.out.println("Successfully requested and stored ticket in "
-            + ccacheFile.getAbsolutePath());
-
-        if (ktOptions.contains(KinitOption.SERVICE)) {
-            System.out.println("Use tgt to request a service ticket.");
-            String servicePrincipal = ktOptions.getStringOption(KinitOption.SERVICE);
-            SgtTicket sgtTicket;
-            try {
-                sgtTicket = krbClient.requestSgt(tgt, servicePrincipal);
-            } catch (KrbException e) {
-                System.err.println("kinit: " + e.getKrbErrorCode().getMessage());
-                return;
-            }
-
-            System.out.println(sgtTicket.getEncKdcRepPart().getSname().getName() + ": knvo = "
-                + sgtTicket.getTicket().getEncryptedEncPart().getKvno());
-        }
-    }
-
-    /**
-     * Init the client.
-     */
-    private static KrbClient getClient(File confDir) throws KrbException {
-        KrbClient krbClient;
-
-        if (confDir != null) {
-            krbClient = new KrbClient(confDir);
-        } else {
-            krbClient = new KrbClient();
-        }
-
-        krbClient.init();
-        return krbClient;
-    }
-
-    /**
-     * Get credential cache file name if not specified.
-     */
-    private static String getCcacheName(KrbClient krbClient) {
-        final String ccacheNameEnv = System.getenv("KRB5CCNAME");
-        final String ccacheNameConf = krbClient.getSetting().getKrbConfig().getString("default_ccache_name");
-        String ccacheName;
-        if (ccacheNameEnv != null) {
-            ccacheName = ccacheNameEnv;
-        } else if (ccacheNameConf != null) {
-            ccacheName = ccacheNameConf;
-        } else {
-            StringBuilder uid = new StringBuilder();
-            try {
-                //Get UID through "id -u" command
-                String command = "id -u";
-                Process child = Runtime.getRuntime().exec(command);
-                InputStream in = child.getInputStream();
-                int c;
-                while ((c = in.read()) != -1) {
-                    uid.append((char) c);
-                }
-                in.close();
-            } catch (IOException e) {
-                System.err.println("Failed to get UID.");
-                System.exit(1);
-            }
-            ccacheName = "krb5cc_" + uid.toString().trim();
-            ccacheName = SysUtil.getTempDir().toString() + "/" + ccacheName;
-        }
-
-        return ccacheName;
-    }
-
-    public static void main(String[] args) {
-        KOptions ktOptions = new KOptions();
-        KinitOption kto;
-        String principal = null;
-
-        int i = 0;
-        String opt, param, error;
-        while (i < args.length) {
-            error = null;
-
-            opt = args[i++];
-            if (opt.startsWith("-")) {
-                kto = KinitOption.fromName(opt);
-                if (kto == KinitOption.NONE) {
-                    error = "Invalid option:" + opt;
-                    System.err.println(error);
-                    break;
-                }
-            } else {
-                principal = opt;
-                kto = KinitOption.NONE;
-            }
-
-            if (kto != KinitOption.NONE && kto.getOptionInfo().getType() != KOptionType.NOV) {
-                // require a parameter
-                param = null;
-                if (i < args.length) {
-                    param = args[i++];
-                }
-                if (param != null) {
-                    KOptions.parseSetValue(kto.getOptionInfo(), param);
-                } else {
-                    error = "Option " + opt + " require a parameter";
-                }
-            }
-
-            if (error != null) {
-                printUsage(error);
-            }
-            if (kto != KinitOption.NONE) {
-                ktOptions.add(kto);
-            }
-        }
-
-        if (!ktOptions.contains(KinitOption.CONF_DIR)) {
-            printUsage("No conf dir given.");
-        }
-
-        if (principal == null) {
-            if (!ktOptions.contains(KinitOption.SERVICE) && !ktOptions.contains(KinitOption.KRB5_CACHE)) {
-                printUsage("No principal is specified");
-            } else if (ktOptions.contains(KinitOption.SERVICE) && !ktOptions.contains(KinitOption.KRB5_CACHE)) {
-                printKvnoUsage("No credential cache file given.");
-            }
-        }
-
-        requestTicket(principal, ktOptions);
-        System.exit(0);
-    }
-
-    /**
-     * Convert kinit tool options to KOptions.
-     * @param toolOptions
-     * @return KOptions
-     */
-    static KOptions convertOptions(KOptions toolOptions) {
-        KOptions results = new KOptions();
-
-        for (KOption toolOpt : toolOptions.getOptions()) {
-            KOptionInfo kOptionInfo = toolOpt.getOptionInfo();
-            KOptionGroup group = kOptionInfo.getGroup();
-            KOption kOpt = null;
-
-            if (group == KrbOptionGroup.KRB) {
-                kOpt = KrbOption.fromOptionName(kOptionInfo.getName());
-            } else if (group == KrbOptionGroup.PKINIT) {
-                kOpt = PkinitOption.fromOptionName(kOptionInfo.getName());
-            } else if (group == KrbOptionGroup.TOKEN) {
-                kOpt = TokenOption.fromOptionName(kOptionInfo.getName());
-            } else if (group == KrbOptionGroup.KDC_FLAGS) {
-                kOpt = KrbKdcOption.fromOptionName(kOptionInfo.getName());
-            }
-            if (kOpt != null && kOpt.getOptionInfo() != KrbOption.NONE.getOptionInfo()) {
-                kOpt.getOptionInfo().setValue(toolOpt.getOptionInfo().getValue());
-                results.add(kOpt);
-            }
-        }
-
-        return results;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/klist/KlistOption.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/klist/KlistOption.java b/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/klist/KlistOption.java
deleted file mode 100644
index dab4d47..0000000
--- a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/klist/KlistOption.java
+++ /dev/null
@@ -1,66 +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.hadoop.has.tool.client.klist;
-
-import org.apache.kerby.KOption;
-import org.apache.kerby.KOptionInfo;
-import org.apache.kerby.KOptionType;
-
-public enum KlistOption implements KOption {
-    NONE(null),
-    CREDENTIALS_CACHE(new KOptionInfo("-c", "specifies path of credentials cache",
-        KOptionType.STR)),
-    KEYTAB(new KOptionInfo("-k", "specifies keytab")),
-    DEFAULT_CLIENT_KEYTAB(new KOptionInfo("-i", "uses default client keytab if no name given")),
-    LIST_CREDENTIAL_CACHES(new KOptionInfo("-l", "list credential caches in collection")),
-    ALL_CREDENTIAL_CACHES(new KOptionInfo("-A", "shows content of all credential caches")),
-    ENCRYPTION_TYPE(new KOptionInfo("-e", "shows encryption type")),
-    KERBEROS_VERSION(new KOptionInfo("-V", "shows Kerberos version")),
-    AUTHORIZATION_DATA_TYPE(new KOptionInfo("-d", "shows the submitted authorization data type")),
-    CREDENTIALS_FLAGS(new KOptionInfo("-f", "show credential flags")),
-    EXIT_TGT_EXISTENCE(new KOptionInfo("-s", "sets exit status based on valid tgt existence")),
-    DISPL_ADDRESS_LIST(new KOptionInfo("-a", "displays the address list")),
-    NO_REVERSE_RESOLVE(new KOptionInfo("-n", "do not reverse resolve")),
-    SHOW_KTAB_ENTRY_TS(new KOptionInfo("-t", "shows keytab entry timestamps")),
-    SHOW_KTAB_ENTRY_KEY(new KOptionInfo("-K", "show keytab entry keys"));
-
-    private final KOptionInfo optionInfo;
-
-    KlistOption(KOptionInfo optionInfo) {
-        this.optionInfo = optionInfo;
-    }
-
-    @Override
-    public KOptionInfo getOptionInfo() {
-        return optionInfo;
-    }
-
-    public static KlistOption fromName(String name) {
-        if (name != null) {
-            for (KlistOption ko : values()) {
-                if (ko.optionInfo != null
-                        && ko.optionInfo.getName().equals(name)) {
-                    return ko;
-                }
-            }
-        }
-        return NONE;
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/klist/KlistTool.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/klist/KlistTool.java b/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/klist/KlistTool.java
deleted file mode 100644
index 7143c04..0000000
--- a/has/has-tool/has-client-tool/src/main/java/org/apache/hadoop/has/tool/client/klist/KlistTool.java
+++ /dev/null
@@ -1,293 +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.hadoop.has.tool.client.klist;
-
-import org.apache.kerby.KOptionType;
-import org.apache.kerby.KOptions;
-import org.apache.kerby.kerberos.kerb.KrbException;
-import org.apache.kerby.kerberos.kerb.ccache.Credential;
-import org.apache.kerby.kerberos.kerb.ccache.CredentialCache;
-import org.apache.kerby.kerberos.kerb.client.KrbClient;
-import org.apache.kerby.kerberos.kerb.keytab.Keytab;
-import org.apache.kerby.kerberos.kerb.keytab.KeytabEntry;
-import org.apache.kerby.kerberos.kerb.type.base.PrincipalName;
-import org.apache.kerby.util.HexUtil;
-import org.apache.kerby.util.OSUtil;
-import org.apache.kerby.util.SysUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-
-/**
- * klist like tool
- *
- * Ref. MIT klist command tool usage.
- */
-public class KlistTool {
-    private static final Logger LOG = LoggerFactory.getLogger(KlistTool.class);
-
-    private static final String USAGE = (OSUtil.isWindows()
-        ? "Usage: bin\\klist.cmd" : "Usage: sh bin/klist.sh")
-            + " [-e] [-V] [[-c] [-l] [-A] [-d] [-f] [-s] "
-            + "[-a [-n]]] [-k [-t] [-K]] [name]\n"
-            + "\t-c specifies credentials cache\n"
-            + "\t-k specifies keytab\n"
-            + "\t   (Default is credentials cache)\n"
-            + "\t-i uses default client keytab if no name given\n"
-            + "\t-l lists credential caches in collection\n"
-            + "\t-A shows content of all credential caches\n"
-            + "\t-e shows the encryption type\n"
-            + "\t-V shows the Kerberos version and exits\n"
-            + "\toptions for credential caches:\n"
-            + "\t\t-d shows the submitted authorization data types\n"
-            + "\t\t-f shows credentials flags\n"
-            + "\t\t-s sets exit status based on valid tgt existence\n"
-            + "\t\t-a displays the address list\n"
-            + "\t\t\t-n do not reverse-resolve\n"
-            + "\toptions for keytabs:\n"
-            + "\t\t-t shows keytab entry timestamps\n"
-            + "\t\t-K shows keytab entry keys\n";
-
-    // option "-k" hava a optional parameter, "/etc/krb5.keytab" if not specified
-    private static String keytabFilePath = null;
-
-    private static void printUsage(String error) {
-        System.err.println(error + "\n");
-        System.err.println(USAGE);
-        System.exit(-1);
-    }
-
-    private static int printCredentialCacheInfo(KOptions klOptions) {
-        CredentialCache cc = new CredentialCache();
-        List<Credential> credentials;
-        InputStream cis = null;
-        String fileName;
-
-        if (!klOptions.contains(KlistOption.CREDENTIALS_CACHE)) {
-            fileName = getCcacheName();
-        } else {
-            fileName = klOptions.getStringOption(KlistOption.CREDENTIALS_CACHE);
-        }
-        try {
-            cis = Files.newInputStream(Paths.get(fileName));
-            cc.load(cis);
-        } catch (IOException e) {
-            LOG.error("Failed to open CredentialCache from file: " + fileName + ". " + e.toString());
-        } finally {
-            try {
-                if (cis != null) {
-                    cis.close();
-                }
-            } catch (IOException e) {
-                LOG.warn("Fail to close input stream. " + e);
-            }
-        }
-
-        if (cc != null) {
-            credentials = cc.getCredentials();
-
-            System.out.println("Ticket cache: " + fileName);
-            System.out.println("Default principal: " + cc.getPrimaryPrincipal().getName());
-
-            if (credentials.isEmpty()) {
-                System.out.println("No credential has been cached.");
-            } else {
-                DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-
-                System.out.println("Valid starting\t\tExpires\t\t\tService principal");
-
-                for (Credential crd : credentials) {
-                    System.out.println(df.format(crd.getStartTime().getTime()) + "\t"
-                        + df.format(crd.getEndTime().getTime()) + "\t"
-                        + crd.getServerName() + "\n"
-                        + "\t" + "renew until" + "\t" + df.format(crd.getRenewTill().getTime()));
-                }
-            }
-        }
-
-        return 0;
-    }
-
-    /**
-     * Get credential cache file name if not specified.
-     */
-    private static String getCcacheName() {
-        String ccacheName;
-        String ccacheNameEnv = System.getenv("KRB5CCNAME");
-        String ccacheNameConf = null;
-        File confDir = new File("/etc");
-        try {
-            KrbClient krbClient = new KrbClient(confDir);
-            ccacheNameConf = krbClient.getSetting().getKrbConfig().getString("default_ccache_name");
-        } catch (KrbException e) {
-            System.err.println("Create krbClient failed: " + e.getMessage());
-            System.exit(1);
-        }
-        if (ccacheNameEnv != null) {
-            ccacheName = ccacheNameEnv;
-        } else if (ccacheNameConf != null) {
-            ccacheName = ccacheNameConf;
-        } else {
-            StringBuilder uid = new StringBuilder();
-            try {
-                //Get UID through "id -u" command
-                String command = "id -u";
-                Process child = Runtime.getRuntime().exec(command);
-                InputStream in = child.getInputStream();
-                int c;
-                while ((c = in.read()) != -1) {
-                    uid.append((char) c);
-                }
-                in.close();
-            } catch (IOException e) {
-                System.err.println("Failed to get UID.");
-                System.exit(1);
-            }
-            ccacheName = "krb5cc_" + uid.toString().trim();
-            ccacheName = SysUtil.getTempDir().toString() + "/" + ccacheName;
-        }
-
-        return ccacheName;
-    }
-
-    private static int printKeytabInfo(KOptions klOptions) {
-        String[] header = new String[4];
-        header[0] = "KVNO Principal\n"
-                + "---- --------------------------------------------------------------------------";
-        header[1] = header[0];
-        header[2] = "KVNO Timestamp           Principal\n"
-                + "---- ------------------- ------------------------------------------------------";
-        header[3] = header[2];
-        int outputIndex = 0;
-        if (klOptions.contains(KlistOption.SHOW_KTAB_ENTRY_TS)) {
-            outputIndex |= 2;
-        }
-        if (klOptions.contains(KlistOption.SHOW_KTAB_ENTRY_KEY)) {
-            outputIndex |= 1;
-        }
-        System.out.println("Keytab name: FILE:" + keytabFilePath);
-        try {
-            File keytabFile = new File(keytabFilePath);
-            if (!keytabFile.exists()) {
-                System.out.println("klist: Key table file '" + keytabFilePath + "' not found. ");
-                return 0;
-            }
-            System.out.println(header[outputIndex]);
-            SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
-            Keytab keytab = Keytab.loadKeytab(keytabFile);
-            List<PrincipalName> principals = keytab.getPrincipals();
-            for (PrincipalName principal : principals) {
-                List<KeytabEntry> keytabEntries = keytab.getKeytabEntries(principal);
-                for (KeytabEntry entry : keytabEntries) {
-                    StringBuilder sb = new StringBuilder();
-                    sb.append(String.format("%-4d ", entry.getKvno()));
-                    if ((outputIndex & 2) != 0) {
-                        Date date = new Date(entry.getTimestamp().getTime());
-                        sb.append(format.format(date));
-                        sb.append(' ');
-                    }
-                    sb.append(String.format("%s ", principal.getName()));
-                    if ((outputIndex & 1) != 0) {
-                        sb.append("(0x");
-                        sb.append(HexUtil.bytesToHex(entry.getKey().getKeyData()));
-                        sb.append(")");
-                    }
-                    System.out.println(sb);
-                }
-            }
-
-        } catch (IOException e) {
-            System.err.println("klist: Error while scan key table file '" + keytabFilePath + "'");
-        }
-        return 0;
-    }
-
-    private static int printInfo(KOptions klOptions) {
-        if (klOptions.contains(KlistOption.KEYTAB)) {
-            return printKeytabInfo(klOptions);
-        }
-        return printCredentialCacheInfo(klOptions);
-    }
-
-    public static void main(String[] args) throws Exception {
-        KOptions klOptions = new KOptions();
-        KlistOption klopt;
-        // String name = null;
-
-        int i = 0;
-        String opt, value, error;
-        while (i < args.length) {
-            error = null;
-            opt = args[i++];
-
-            if (opt.startsWith("-")) {
-                klopt = KlistOption.fromName(opt);
-                if (klopt == KlistOption.NONE) {
-                    error = "Invalid option:" + opt;
-                }
-            } else {
-                if (keytabFilePath == null && klOptions.contains(KlistOption.KEYTAB)) {
-                    keytabFilePath = opt;
-                }
-                break;
-            }
-
-            if (error == null && klopt.getOptionInfo().getType() != KOptionType.NOV) {
-                //needs value for this parameter
-                value = null;
-                if (i < args.length) {
-                    value = args[i++];
-                }
-                if (value != null) {
-                    KOptions.parseSetValue(klopt.getOptionInfo(), value);
-                } else {
-                    error = "Option" + klopt + "requires a following value";
-                }
-            }
-
-            if (error != null) {
-                printUsage(error);
-            }
-
-            klOptions.add(klopt);
-            if (klOptions.contains(KlistOption.KEYTAB)
-                && klOptions.contains(KlistOption.CREDENTIALS_CACHE)) {
-                error = "Can not use '-c' and '-k' at the same time ";
-                printUsage(error);
-            }
-        }
-
-        if (keytabFilePath == null) {
-            keytabFilePath = "/etc/krb5.keytab";
-        }
-
-        int errNo = KlistTool.printInfo(klOptions);
-        System.exit(errNo);
-    }
-}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/HadminRemoteTool.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/HadminRemoteTool.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/HadminRemoteTool.java
new file mode 100644
index 0000000..71300c0
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/HadminRemoteTool.java
@@ -0,0 +1,164 @@
+/**
+ *  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.has.tool.client.hadmin.remote;
+
+import org.apache.kerby.has.client.HasAdminClient;
+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.has.tool.client.hadmin.remote.cmd.HadminRemoteCmd;
+import org.apache.kerby.has.tool.client.hadmin.remote.cmd.HasRemoteAddPrincipalCmd;
+import org.apache.kerby.has.tool.client.hadmin.remote.cmd.HasRemoteCreatePrincipalsCmd;
+import org.apache.kerby.has.tool.client.hadmin.remote.cmd.HasRemoteDeletePrincipalCmd;
+import org.apache.kerby.has.tool.client.hadmin.remote.cmd.HasRemoteDisableConfCmd;
+import org.apache.kerby.has.tool.client.hadmin.remote.cmd.HasRemoteEnableConfCmd;
+import org.apache.kerby.has.tool.client.hadmin.remote.cmd.HasRemoteExportKeytabsCmd;
+import org.apache.kerby.has.tool.client.hadmin.remote.cmd.HasRemoteGetHostRolesCmd;
+import org.apache.kerby.has.tool.client.hadmin.remote.cmd.HasRemoteGetPrincipalsCmd;
+import org.apache.kerby.has.tool.client.hadmin.remote.cmd.HasRemoteRenamePrincipalCmd;
+import org.apache.kerby.util.OSUtil;
+
+import java.io.File;
+import java.util.Scanner;
+
+public class HadminRemoteTool {
+
+    private static final String PROMPT = HadminRemoteTool.class.getSimpleName() + ".remote";
+    private static final String USAGE = (OSUtil.isWindows()
+        ? "Usage: bin\\hadmin-remote.cmd" : "Usage: sh bin/hadmin-remote.sh")
+        + " <conf-file>\n"
+        + "\tExample:\n"
+        + "\t\t"
+        + (OSUtil.isWindows()
+        ? "bin\\hadmin-remote.cmd" : "sh bin/hadmin-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"
+        + "get_hostroles, hostroles\n"
+        + "                         Get hostRoles\n"
+        + "export_keytabs, expkeytabs\n"
+        + "                         Export keytabs\n"
+        + "create_principals, creprincs\n"
+        + "                         Create principals\n"
+        + "enable_configure, enable\n"
+        + "                         Enable configure\n"
+        + "disable_configure, disable\n"
+        + "                         Disable configure\n";
+
+    public static void main(String[] args) {
+        HasAdminClient hadmin;
+        HasAuthAdminClient authHasAdminClient = null;
+
+        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;
+        }
+
+        hadmin = new HasAdminClient(hasConfig);
+
+        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(hadmin, authHasAdminClient, input);
+                } catch (HasException e) {
+                    System.err.println(e.getMessage());
+                }
+                System.out.print(PROMPT + ": ");
+                input = scanner.nextLine();
+            }
+        }
+    }
+
+    private static void execute(HasAdminClient hadmin, HasAuthAdminClient hasAuthAdminClient,
+                               String input) throws HasException {
+        input = input.trim();
+        if (input.startsWith("cmd")) {
+            System.out.println(LEGAL_COMMANDS);
+            return;
+        }
+        HadminRemoteCmd executor;
+
+        String[] items = input.split("\\s+");
+        String cmd = items[0];
+
+        if (cmd.equals("add_principal")
+            || cmd.equals("addprinc")) {
+            executor = new HasRemoteAddPrincipalCmd(hadmin, hasAuthAdminClient);
+        } else if (cmd.equals("delete_principal")
+            || cmd.equals("delprinc")) {
+            executor = new HasRemoteDeletePrincipalCmd(hadmin, hasAuthAdminClient);
+        } else if (cmd.equals("rename_principal")
+            || cmd.equals("renprinc")) {
+            executor = new HasRemoteRenamePrincipalCmd(hadmin, hasAuthAdminClient);
+        } else if (cmd.equals("list_principals")
+            || cmd.equals("listprincs")) {
+            executor = new HasRemoteGetPrincipalsCmd(hadmin, hasAuthAdminClient);
+        } else if (cmd.equals("get_hostroles")
+            || cmd.equals("hostroles")) {
+            executor = new HasRemoteGetHostRolesCmd(hadmin, hasAuthAdminClient);
+        } else if (cmd.equals("create_principals")
+            || cmd.equals("creprincs")) {
+            executor = new HasRemoteCreatePrincipalsCmd(hadmin, hasAuthAdminClient);
+        } else if (cmd.equals("export_keytabs")
+            || cmd.equals("expkeytabs")) {
+            executor = new HasRemoteExportKeytabsCmd(hadmin, hasAuthAdminClient);
+        } else if (cmd.equals("enable_configure")
+            || cmd.equals("enable")) {
+            executor = new HasRemoteEnableConfCmd(hadmin, hasAuthAdminClient);
+        } else if (cmd.equals("disable_configure")
+            || cmd.equals("disable")) {
+            executor = new HasRemoteDisableConfCmd(hadmin, hasAuthAdminClient);
+        } else {
+            System.out.println(LEGAL_COMMANDS);
+            return;
+        }
+        executor.execute(items);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HadminRemoteCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HadminRemoteCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HadminRemoteCmd.java
new file mode 100644
index 0000000..d94c3d6
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HadminRemoteCmd.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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+
+public abstract class HadminRemoteCmd {
+
+    private HasAdminClient hadmin;
+    private HasAuthAdminClient authHadmin;
+
+    public HadminRemoteCmd(HasAdminClient hadmin, HasAuthAdminClient authHadminClient) {
+        this.hadmin = hadmin;
+        this.authHadmin = authHadminClient;
+    }
+
+    protected HasAdminClient getHadmin() {
+        return hadmin;
+    }
+
+    protected HasAuthAdminClient getAuthHadmin() {
+        return authHadmin;
+    }
+
+    /**
+     * Execute the hadmin cmd.
+     * @param input Input cmd to execute
+     */
+    public abstract void execute(String[] input) throws HasException;
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteAddPrincipalCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteAddPrincipalCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteAddPrincipalCmd.java
new file mode 100644
index 0000000..746d497
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteAddPrincipalCmd.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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+
+/**
+ * Remote add principal cmd
+ */
+public class HasRemoteAddPrincipalCmd extends HadminRemoteCmd {
+
+    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 HasRemoteAddPrincipalCmd(HasAdminClient hadmin, HasAuthAdminClient authHadmin) {
+        super(hadmin, authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws HasException {
+        if (items.length < 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        String clientPrincipal = items[items.length - 1];
+
+        HasAdminClient hasAdminClient;
+        if (getAuthHadmin() != null) {
+            hasAdminClient = getAuthHadmin();
+        } else {
+            hasAdminClient = getHadmin();
+        }
+
+        if (!items[1].startsWith("-")) {
+            hasAdminClient.addPrincipal(clientPrincipal);
+        } else if (items[1].startsWith("-randkey")) {
+            hasAdminClient.addPrincipal(clientPrincipal);
+        } else if (items[1].startsWith("-pw")) {
+            String password = items[2];
+            hasAdminClient.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/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteCreatePrincipalsCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteCreatePrincipalsCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteCreatePrincipalsCmd.java
new file mode 100644
index 0000000..95208be
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteCreatePrincipalsCmd.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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class HasRemoteCreatePrincipalsCmd extends HadminRemoteCmd {
+    private static final String USAGE = "\nUsage: create_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\tcreate_principals hostroles.txt\n";
+
+    public HasRemoteCreatePrincipalsCmd(HasAdminClient hadmin, HasAuthAdminClient authHadmin) {
+        super(hadmin, authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws HasException {
+        //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;
+        }
+
+        HasAdminClient hasAdminClient;
+        if (getAuthHadmin() != null) {
+            hasAdminClient = getAuthHadmin();
+        } else {
+            hasAdminClient = getHadmin();
+        }
+
+        BufferedReader reader;
+        try {
+            reader = new BufferedReader(new FileReader(hostRoles));
+        } catch (FileNotFoundException e) {
+            throw new HasException("File not exist", e);
+        }
+        StringBuilder sb = new StringBuilder();
+        String tempString;
+        try {
+            while ((tempString = reader.readLine()) != null) {
+                sb.append(tempString);
+            }
+        } catch (IOException e) {
+            throw new HasException("Errors occurred when read line. ", e);
+        }
+        hasAdminClient.requestCreatePrincipals(sb.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteDeletePrincipalCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteDeletePrincipalCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteDeletePrincipalCmd.java
new file mode 100644
index 0000000..4ca2f84
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteDeletePrincipalCmd.java
@@ -0,0 +1,89 @@
+/**
+ *  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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+
+import java.io.Console;
+import java.util.Scanner;
+
+/**
+ * Remote delete principal cmd
+ */
+public class HasRemoteDeletePrincipalCmd extends HadminRemoteCmd {
+
+    public static final String USAGE = "Usage: delete_principal <principal-name>\n"
+        + "\tExample:\n"
+        + "\t\tdelete_principal alice\n";
+
+    public HasRemoteDeletePrincipalCmd(HasAdminClient hadmin, HasAuthAdminClient authHadmin) {
+        super(hadmin, authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws HasException {
+        if (items.length < 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        HasAdminClient hasAdminClient;
+        if (getAuthHadmin() != null) {
+            hasAdminClient = getAuthHadmin();
+        } else {
+            hasAdminClient = getHadmin();
+        }
+
+        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")) {
+            hasAdminClient.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/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteDisableConfCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteDisableConfCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteDisableConfCmd.java
new file mode 100644
index 0000000..05f0271
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteDisableConfCmd.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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+
+/**
+ * Remote add principal cmd
+ */
+public class HasRemoteDisableConfCmd extends HadminRemoteCmd {
+
+    public static final String USAGE = "Usage: disable_configure\n"
+            + "\tExample:\n"
+            + "\t\tdisable\n";
+
+    public HasRemoteDisableConfCmd(HasAdminClient hadmin, HasAuthAdminClient authHadmin) {
+        super(hadmin, authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws HasException {
+        HasAdminClient hasAdminClient;
+        if (getAuthHadmin() != null) {
+            hasAdminClient = getAuthHadmin();
+        } else {
+            hasAdminClient = getHadmin();
+        }
+        hasAdminClient.setEnableOfConf("false");
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteEnableConfCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteEnableConfCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteEnableConfCmd.java
new file mode 100644
index 0000000..cb1ecfa
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteEnableConfCmd.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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+
+/**
+ * Remote add principal cmd
+ */
+public class HasRemoteEnableConfCmd extends HadminRemoteCmd {
+
+    public static final String USAGE = "Usage: enable_configure\n"
+            + "\tExample:\n"
+            + "\t\tenable\n";
+
+    public HasRemoteEnableConfCmd(HasAdminClient hadmin, HasAuthAdminClient authHadmin) {
+        super(hadmin, authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws HasException {
+        HasAdminClient hasAdminClient;
+        if (getAuthHadmin() != null) {
+            hasAdminClient = getAuthHadmin();
+        } else {
+            hasAdminClient = getHadmin();
+        }
+        hasAdminClient.setEnableOfConf("true");
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteExportKeytabsCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteExportKeytabsCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteExportKeytabsCmd.java
new file mode 100644
index 0000000..ba11b3b
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteExportKeytabsCmd.java
@@ -0,0 +1,58 @@
+/**
+ *  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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+
+public class HasRemoteExportKeytabsCmd extends HadminRemoteCmd {
+    private static final String USAGE = "\nUsage: export_keytabs <host> [role]\n"
+            + "\tExample:\n"
+            + "\t\texport_keytabs host1 HDFS\n";
+
+    public HasRemoteExportKeytabsCmd(HasAdminClient hadmin, HasAuthAdminClient authHadmin) {
+        super(hadmin, authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws HasException {
+        //TODO add save path option
+        //String param = items[0];
+        if (items.length < 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        HasAdminClient hasAdminClient;
+        if (getAuthHadmin() != null) {
+            hasAdminClient = getAuthHadmin();
+        } else {
+            hasAdminClient = getHadmin();
+        }
+
+        String host = items[1];
+        String role = "";
+        if (items.length >= 3) {
+            role = items[2];
+        }
+        hasAdminClient.getKeytabByHostAndRole(host, role);
+    }
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteGetHostRolesCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteGetHostRolesCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteGetHostRolesCmd.java
new file mode 100644
index 0000000..255ee87
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteGetHostRolesCmd.java
@@ -0,0 +1,68 @@
+/**
+ *  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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+
+public class HasRemoteGetHostRolesCmd extends HadminRemoteCmd {
+    private static final String USAGE = "Usage: get_hostroles\n"
+            + "\tExample:\n"
+            + "\t\tget_hostroles\n";
+
+    public HasRemoteGetHostRolesCmd(HasAdminClient hadmin, HasAuthAdminClient authHadmin) {
+        super(hadmin, authHadmin);
+    }
+
+    @Override
+    public void execute(String[] input) throws HasException {
+        HasAdminClient hasAdminClient = getHadmin();
+        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 HasException("Errors occurred when getting the host roles.", e);
+            }
+        } else {
+            throw new HasException("Could not get hostRoles.");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteGetPrincipalsCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteGetPrincipalsCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteGetPrincipalsCmd.java
new file mode 100644
index 0000000..6c98d38
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteGetPrincipalsCmd.java
@@ -0,0 +1,76 @@
+/**
+ *  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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+
+import java.util.List;
+
+public class HasRemoteGetPrincipalsCmd extends HadminRemoteCmd {
+    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 HasRemoteGetPrincipalsCmd(HasAdminClient hadmin, HasAuthAdminClient authHadmin) {
+        super(hadmin, authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws HasException {
+        if (items.length > 2) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        HasAdminClient hasAdminClient;
+        if (getAuthHadmin() != null) {
+            hasAdminClient = getAuthHadmin();
+        } else {
+            hasAdminClient = getHadmin();
+        }
+
+        List<String> principalLists = null;
+
+        if (items.length == 1) {
+            try {
+                principalLists = hasAdminClient.getPrincipals();
+            } catch (Exception e) {
+                System.err.println("Errors occurred when getting the principals. " + e.getMessage());
+            }
+        } else {
+            //have expression
+            String exp = items[1];
+            principalLists = hasAdminClient.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/a8b1c28f/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteRenamePrincipalCmd.java
----------------------------------------------------------------------
diff --git a/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteRenamePrincipalCmd.java b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteRenamePrincipalCmd.java
new file mode 100644
index 0000000..7125da6
--- /dev/null
+++ b/has/has-tool/has-client-tool/src/main/java/org/apache/kerby/has/tool/client/hadmin/remote/cmd/HasRemoteRenamePrincipalCmd.java
@@ -0,0 +1,91 @@
+/**
+ *  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.has.tool.client.hadmin.remote.cmd;
+
+import org.apache.kerby.has.client.HasAdminClient;
+import org.apache.kerby.has.client.HasAuthAdminClient;
+import org.apache.kerby.has.common.HasException;
+
+import java.io.Console;
+import java.util.Scanner;
+
+/**
+ * Remote rename principal cmd
+ */
+public class HasRemoteRenamePrincipalCmd extends HadminRemoteCmd {
+    public static final String USAGE = "Usage: rename_principal <old_principal_name>"
+        + " <new_principal_name>\n"
+        + "\tExample:\n"
+        + "\t\trename_principal alice bob\n";
+
+    public HasRemoteRenamePrincipalCmd(HasAdminClient hadmin, HasAuthAdminClient authHadmin) {
+        super(hadmin, authHadmin);
+    }
+
+    @Override
+    public void execute(String[] items) throws HasException {
+        if (items.length < 3) {
+            System.err.println(USAGE);
+            return;
+        }
+
+        HasAdminClient hasAdminClient;
+        if (getAuthHadmin() != null) {
+            hasAdminClient = getAuthHadmin();
+        } else {
+            hasAdminClient = getHadmin();
+        }
+
+        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")) {
+            hasAdminClient.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;
+    }
+}