You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by pl...@apache.org on 2016/06/01 01:45:47 UTC
directory-kerby git commit: DIRKRB-574 Implement a concurrent test to
benchmark throughput and latency of kerby KDC. Contributed by Qing.
Repository: directory-kerby
Updated Branches:
refs/heads/trunk f751d3906 -> 741473254
DIRKRB-574 Implement a concurrent test to benchmark throughput and latency of kerby KDC. Contributed by Qing.
Project: http://git-wip-us.apache.org/repos/asf/directory-kerby/repo
Commit: http://git-wip-us.apache.org/repos/asf/directory-kerby/commit/74147325
Tree: http://git-wip-us.apache.org/repos/asf/directory-kerby/tree/74147325
Diff: http://git-wip-us.apache.org/repos/asf/directory-kerby/diff/74147325
Branch: refs/heads/trunk
Commit: 741473254f5891a748aa2942cefe25e3f3e70323
Parents: f751d39
Author: plusplusjiajia <ji...@intel.com>
Authored: Wed Jun 1 09:51:16 2016 +0800
Committer: plusplusjiajia <ji...@intel.com>
Committed: Wed Jun 1 09:51:16 2016 +0800
----------------------------------------------------------------------
.../identitybackend/JsonIdentityBackend.java | 1 +
kerby-dist/tool-dist/bin/kinitConcurrent.cmd | 33 ++
kerby-dist/tool-dist/bin/kinitConcurrent.sh | 33 ++
.../kerby/kerberos/kerb/admin/KadminOption.java | 1 +
.../kerby/kerberos/kerb/admin/LocalKadmin.java | 2 +
.../kerberos/kerb/admin/LocalKadminImpl.java | 8 +
.../tool/kinit/KinitToolWithConcurrence.java | 326 +++++++++++++++++++
.../kerby/kerberos/tool/kadmin/KadminTool.java | 6 +
.../kadmin/command/AddPrincipalsCommand.java | 112 +++++++
9 files changed, 522 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/74147325/kerby-backend/json-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/JsonIdentityBackend.java
----------------------------------------------------------------------
diff --git a/kerby-backend/json-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/JsonIdentityBackend.java b/kerby-backend/json-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/JsonIdentityBackend.java
index ad61967..3908cc5 100644
--- a/kerby-backend/json-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/JsonIdentityBackend.java
+++ b/kerby-backend/json-backend/src/main/java/org/apache/kerby/kerberos/kdc/identitybackend/JsonIdentityBackend.java
@@ -244,6 +244,7 @@ public class JsonIdentityBackend extends AbstractIdentityBackend {
*/
@Override
protected Iterable<String> doGetIdentities() throws KrbException {
+ load();
List<String> principals = new ArrayList<>(identities.keySet());
Collections.sort(principals);
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/74147325/kerby-dist/tool-dist/bin/kinitConcurrent.cmd
----------------------------------------------------------------------
diff --git a/kerby-dist/tool-dist/bin/kinitConcurrent.cmd b/kerby-dist/tool-dist/bin/kinitConcurrent.cmd
new file mode 100644
index 0000000..359e370
--- /dev/null
+++ b/kerby-dist/tool-dist/bin/kinitConcurrent.cmd
@@ -0,0 +1,33 @@
+@echo off
+@rem Licensed to the Apache Software Foundation (ASF) under one
+@rem or more contributor license agreements. See the NOTICE file
+@rem distributed with this work for additional information
+@rem regarding copyright ownership. The ASF licenses this file
+@rem to you under the Apache License, Version 2.0 (the
+@rem "License"); you may not use this file except in compliance
+@rem with the License. You may obtain a copy of the License at
+@rem
+@rem http://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing,
+@rem software distributed under the License is distributed on an
+@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@rem KIND, either express or implied. See the License for the
+@rem specific language governing permissions and limitations
+@rem under the License.
+@rem
+
+set DEBUG=
+set args=%*
+for %%a in (%*) do (
+ if -D == %%a (
+ set DEBUG=-Xdebug -Xrunjdwp:transport=dt_socket,address=8002,server=y,suspend=y
+ set args=%args:-D=%
+ )
+)
+
+java %DEBUG% ^
+-classpath target\lib\* ^
+-DKERBY_LOGFILE=kinit ^
+org.apache.kerby.kerberos.tool.kinit.KinitToolWithConcurrence %args%
+
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/74147325/kerby-dist/tool-dist/bin/kinitConcurrent.sh
----------------------------------------------------------------------
diff --git a/kerby-dist/tool-dist/bin/kinitConcurrent.sh b/kerby-dist/tool-dist/bin/kinitConcurrent.sh
new file mode 100644
index 0000000..7c46052
--- /dev/null
+++ b/kerby-dist/tool-dist/bin/kinitConcurrent.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DEBUG=
+args=
+for var in $*; do
+ if [ X"$var" = X"-D" ]; then
+ DEBUG="-Xdebug -Xrunjdwp:transport=dt_socket,address=8002,server=y,suspend=y"
+ else
+ args="$args $var"
+ fi
+done
+
+java $DEBUG \
+-classpath target/lib/*:. \
+-DKERBY_LOGFILE=kinit \
+org.apache.kerby.kerberos.tool.kinit.KinitToolWithConcurrence $args
+
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/74147325/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
index bdab4d6..0c11fe7 100644
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
+++ b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/KadminOption.java
@@ -30,6 +30,7 @@ public enum KadminOption implements KOption {
LOCKED(new KOptionInfo("-locked", "locked", KOptionType.BOOL)),
FORCE(new KOptionInfo("-force", "force", KOptionType.NOV)),
KVNO(new KOptionInfo("-kvno", "initial key version number", KOptionType.INT)),
+ SIZE(new KOptionInfo("-size", "principal's numbers", KOptionType.STR)),
PW(new KOptionInfo("-pw", "password", KOptionType.STR)),
RANDKEY(new KOptionInfo("-randkey", "random key", KOptionType.NOV)),
KEEPOLD(new KOptionInfo("-keepold", "keep old passowrd", KOptionType.NOV)),
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/74147325/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadmin.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadmin.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadmin.java
index 6125f0b..d8d38f1 100644
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadmin.java
+++ b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadmin.java
@@ -82,4 +82,6 @@ public interface LocalKadmin extends Kadmin {
* @throws KrbException e
*/
KrbIdentity getPrincipal(String principalName) throws KrbException;
+
+ int size() throws KrbException;
}
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/74147325/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadminImpl.java
----------------------------------------------------------------------
diff --git a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadminImpl.java b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadminImpl.java
index 5ba4eb8..9f0f89e 100644
--- a/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadminImpl.java
+++ b/kerby-kerb/kerb-admin/src/main/java/org/apache/kerby/kerberos/kerb/admin/LocalKadminImpl.java
@@ -379,6 +379,14 @@ public class LocalKadminImpl implements LocalKadmin {
}
/**
+ * get size of principal
+ */
+ @Override
+ public int size() throws KrbException {
+ return this.getPrincipals().size();
+ }
+
+ /**
* Fix principal name, making it complete.
*
* @param principal The principal name
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/74147325/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitToolWithConcurrence.java
----------------------------------------------------------------------
diff --git a/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitToolWithConcurrence.java b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitToolWithConcurrence.java
new file mode 100644
index 0000000..7427307
--- /dev/null
+++ b/kerby-tool/client-tool/src/main/java/org/apache/kerby/kerberos/tool/kinit/KinitToolWithConcurrence.java
@@ -0,0 +1,326 @@
+/**
+ * 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.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.util.OSUtil;
+import java.io.File;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * kinit like tool with concurrence
+ *
+ * Ref. MIT kinit command tool usage.aa
+ */
+public class KinitToolWithConcurrence {
+ /**
+ * control the number of request
+ */
+ private static int[] reList = new int[100000];
+ private static String[] prList = new String[10000];
+ private static KOptions ktOptions = new KOptions();
+ private static int thFlag = 0;
+ private static Long startTime = 0L;
+ private static Lock lock = new ReentrantLock();
+ private static int tmpTotals = 0;
+ private static final int INTERVAL = 16;
+
+ 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 void requestTicket(String principal,
+ KOptions ktOptions, int flag) throws KrbException {
+ ktOptions.add(KinitOption.CLIENT_PRINCIPAL, principal);
+
+ File confDir = null;
+ if (ktOptions.contains(KinitOption.CONF_DIR)) {
+ confDir = ktOptions.getDirOption(KinitOption.CONF_DIR);
+ }
+
+ if (ktOptions.contains(KinitOption.ANONYMOUS)) {
+ ktOptions.add(PkinitOption.USE_ANONYMOUS);
+ ktOptions.add(PkinitOption.X509_ANCHORS);
+ } else if (!ktOptions.contains(KinitOption.USE_KEYTAB)) {
+ //If not request tickets by keytab than by password.
+ ktOptions.add(KinitOption.USE_PASSWD);
+ String password = "12";
+ ktOptions.add(KinitOption.USER_PASSWD, password);
+ }
+
+ KrbClient krbClient = null;
+ try {
+ krbClient = getClient(confDir);
+ } catch (KrbException e) {
+ System.err.println("Create krbClient failed: " + e.getMessage());
+ System.exit(1);
+ }
+
+ KOptions results = convertOptions(ktOptions);
+ try {
+ flag *= INTERVAL;
+ while (true) {
+ krbClient.requestTgt(results);
+ reList[flag] += 1;
+ }
+ } catch (KrbException e) {
+ System.err.println("Authentication failed: " + e.getMessage());
+ System.exit(1);
+ }
+ }
+
+ /**
+ * 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;
+ }
+
+ public static void main(String[] args) throws Exception {
+ KinitOption kto;
+ String principalNumbers = null;
+ String startIndex = 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 {
+ principalNumbers = opt;
+ kto = KinitOption.NONE;
+ // require a parameter
+ startIndex = args[i++];
+ }
+
+ 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);
+ }
+ }
+
+ int threadNumbers = Integer.parseInt(principalNumbers);
+ int stIndex = Integer.parseInt(startIndex);
+
+ if (threadNumbers <= 0) {
+ printUsage("principal must be greater than zero");
+ System.exit(-1);
+ }
+
+ for (int j = 0; j < threadNumbers; j++) {
+ int tmpIndex = j + stIndex;
+ String tempName = "E" + tmpIndex + "@EXAMPLE.COM";
+ prList[j] = tempName;
+ }
+
+ for (int j = 0; j < threadNumbers; j++) {
+ Thread th = new Thread(new PreThread());
+ th.start();
+ }
+
+ // statistical
+ int[] tempDelayNumbers = new int[threadNumbers];
+ int[] delayNumbers = new int[threadNumbers];
+ startTime = System.currentTimeMillis();
+ Long timeStamp = System.currentTimeMillis();
+
+ int max = 0;
+ int min = 0;
+
+ System.out.println("Time stamp (sec),Throughput (sec),"
+ + "avgDelay (ms),maxDelay (ms),minDelay (ms)");
+
+ while (true) {
+ Thread.sleep(2000);
+ int temp = 0;
+ Long now = System.currentTimeMillis();
+
+ for (int j = 0; j < threadNumbers; j++) {
+ delayNumbers[j] = reList[j * INTERVAL] - delayNumbers[j];
+ tempDelayNumbers[j] = reList[j * INTERVAL];
+ }
+
+ for (int j = 0; j < threadNumbers; j++) {
+ temp += reList[j * INTERVAL];
+ }
+ float res = (now - startTime) / 1000;
+
+ int totalDelay = 0;
+ for (int j = 0; j < threadNumbers; j++) {
+ if (delayNumbers[j] != 0) {
+ if (delayNumbers[max] < delayNumbers[j]) {
+ max = j;
+ }
+ if (delayNumbers[min] == 0 || delayNumbers[min] > delayNumbers[j]) {
+ min = j;
+ }
+ totalDelay += (now - startTime) / delayNumbers[j];
+ }
+ }
+ if (delayNumbers[min] != 0 && delayNumbers[max] != 0) {
+ System.out.println((now - timeStamp) / 1000 + "," + (temp - tmpTotals) / res
+ + "," + totalDelay / threadNumbers
+ + "," + (now - startTime) / delayNumbers[min] + "," + (now - startTime) / delayNumbers[max]);
+ }
+
+ tmpTotals = temp;
+ startTime = now;
+ }
+
+ }
+
+ public static class PreThread implements Runnable {
+ @Override
+ public void run() {
+ try {
+ request();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void request() throws Exception {
+ int tempFlag = 0;
+ lock.lock();
+ try {
+ tempFlag = thFlag;
+ thFlag++;
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ lock.unlock();
+ }
+ requestTicket(prList[tempFlag], ktOptions, tempFlag);
+ }
+
+ /**
+ * 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;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/74147325/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/KadminTool.java
----------------------------------------------------------------------
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/KadminTool.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/KadminTool.java
index 224c9ed..1c97204 100644
--- a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/KadminTool.java
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/KadminTool.java
@@ -34,6 +34,7 @@ import org.apache.kerby.kerberos.tool.kadmin.command.KeytabRemoveCommand;
import org.apache.kerby.kerberos.tool.kadmin.command.ListPrincipalCommand;
import org.apache.kerby.kerberos.tool.kadmin.command.ModifyPrincipalCommand;
import org.apache.kerby.kerberos.tool.kadmin.command.RenamePrincipalCommand;
+import org.apache.kerby.kerberos.tool.kadmin.command.AddPrincipalsCommand;
import org.apache.kerby.util.OSUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -56,6 +57,8 @@ public class KadminTool {
+ "\n"
+ "add_principal, addprinc, ank\n"
+ " Add principal\n"
+ + "batch_anks, batch\n"
+ + " Add principals\n"
+ "delete_principal, delprinc\n"
+ " Delete principal\n"
+ "modify_principal, modprinc\n"
@@ -121,6 +124,9 @@ public class KadminTool {
|| command.startsWith("addprinc")
|| command.startsWith("ank")) {
executor = new AddPrincipalCommand(kadmin);
+ } else if (command.startsWith("batch_anks")
+ || command.startsWith("batch")) {
+ executor = new AddPrincipalsCommand(kadmin);
} else if (command.startsWith("ktadd")
|| command.startsWith("xst")) {
executor = new KeytabAddCommand(kadmin);
http://git-wip-us.apache.org/repos/asf/directory-kerby/blob/74147325/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/command/AddPrincipalsCommand.java
----------------------------------------------------------------------
diff --git a/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/command/AddPrincipalsCommand.java b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/command/AddPrincipalsCommand.java
new file mode 100644
index 0000000..32fe808
--- /dev/null
+++ b/kerby-tool/kdc-tool/src/main/java/org/apache/kerby/kerberos/tool/kadmin/command/AddPrincipalsCommand.java
@@ -0,0 +1,112 @@
+/**
+ * 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.kadmin.command;
+
+import org.apache.kerby.KOptions;
+import org.apache.kerby.kerberos.kerb.KrbException;
+import org.apache.kerby.kerberos.kerb.admin.LocalKadmin;
+import org.apache.kerby.kerberos.kerb.admin.KadminOption;
+import org.apache.kerby.kerberos.tool.kadmin.ToolUtil;
+
+public class AddPrincipalsCommand extends KadminCommand {
+ private static final String USAGE = "Usage: add_principals [options]\n"
+ + "\toptions are:\n"
+ + "[-pwexpire pwexpdate] [-maxlife maxtixlife]\n"
+ + "\t\t[-kvno kvno] [-policy policy] [-clearpolicy]\n"
+ + "\t\t[-size principal's numbers,must be greater than zero]\n"
+ + "\t\t[-e keysaltlist]\n"
+ + "\t\t[{+|-}attribute]\n"
+ + "\tattributes are:\n"
+ + "\t\tallow_postdated allow_forwardable allow_tgs_req allow_renewable\n"
+ + "\t\tallow_proxiable allow_dup_skey allow_tix requires_preauth\n"
+ + "\t\trequires_hwauth needchange allow_svr password_changing_service\n"
+ + "\t\tok_as_delegate ok_to_auth_as_delegate no_auth_data_required\n"
+ + "\n"
+ + "\twhere,\n"
+ + "\t[-x db_princ_args]* - any number of database specific arguments.\n"
+ + "\t\t\tLook at each database documentation for supported arguments.\n"
+ + "\tExample:\n"
+ + "\t\tbatch_anks -expire 23/04/15:01:01:01 -kvno 1 -size 6";
+
+
+ private KOptions kOptions;
+
+ public AddPrincipalsCommand(LocalKadmin kadmin) {
+ super(kadmin);
+ }
+
+ @Override
+ public void execute(String input) {
+ String[] commands = input.split("\\s+");
+ if (commands.length < 2) {
+ System.err.println(USAGE);
+ return;
+ }
+ kOptions = ToolUtil.parseOptions(commands, 1, commands.length - 1);
+
+ int size;
+ if (kOptions.contains(KadminOption.SIZE)) {
+ String sizeTemp = kOptions.getStringOption(KadminOption.SIZE);
+
+ String isNum = "^[1-9][0-9]+";
+ if (sizeTemp.matches(isNum)) {
+ size = Integer.parseInt(sizeTemp);
+ } else {
+ System.err.println(USAGE);
+ return;
+ }
+ } else {
+ System.err.println(USAGE);
+ return;
+ }
+
+ if (size <= 0) {
+ System.err.println(USAGE);
+ return;
+ }
+
+ int existNumbers = 0;
+ try {
+ existNumbers = getKadmin().size();
+ } catch (KrbException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ addPrincipalForSize(size, existNumbers);
+ }
+
+ private void addPrincipalForSize(int size, int existNumbers) {
+ int i = 0;
+ while (i < size) {
+ try {
+ int temp = i + existNumbers;
+ String principalName = "E" + temp + "@EXAMPLE.COM";
+ String password = "12";
+ getKadmin().addPrincipal(principalName, password, kOptions);
+ } catch (KrbException e) {
+ e.printStackTrace();
+ }
+ i++;
+ }
+
+ System.out.println("Principals created");
+ }
+}