| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.kerby.kerberos.tool.admin.local; |
| |
| import org.apache.kerby.KOptions; |
| import org.apache.kerby.has.common.HasException; |
| import org.apache.kerby.has.server.admin.LocalHadmin; |
| import org.apache.kerby.kerberos.kerb.KrbException; |
| import org.apache.kerby.kerberos.kerb.admin.kadmin.KadminOption; |
| import org.apache.kerby.kerberos.kerb.admin.kadmin.local.LocalKadmin; |
| import org.apache.kerby.kerberos.kerb.admin.kadmin.local.LocalKadminImpl; |
| import org.apache.kerby.kerberos.tool.admin.local.cmd.AddPrincipalsAndDeployKeytabsCommand; |
| import org.apache.kerby.kerberos.tool.admin.local.cmd.AddPrincipalsCommand; |
| import org.apache.kerby.kerberos.tool.admin.local.cmd.DeployHTTPSCertsCommand; |
| import org.apache.kerby.kerberos.tool.admin.local.cmd.DisableConfigureCommand; |
| import org.apache.kerby.kerberos.tool.admin.local.cmd.EnableConfigureCommand; |
| import org.apache.kerby.kerberos.tool.admin.local.cmd.ExportKeytabsCommand; |
| import org.apache.kerby.kerberos.tool.admin.local.cmd.GetHostRolesCommand; |
| import org.apache.kerby.kerberos.tool.admin.local.cmd.HadminCommand; |
| import org.apache.kerby.kerberos.tool.kadmin.AuthUtil; |
| import org.apache.kerby.kerberos.tool.kadmin.Krb5Conf; |
| import org.apache.kerby.kerberos.tool.kadmin.ToolUtil; |
| import org.apache.kerby.kerberos.tool.kadmin.command.AddPrincipalCommand; |
| import org.apache.kerby.kerberos.tool.kadmin.command.ChangePasswordCommand; |
| import org.apache.kerby.kerberos.tool.kadmin.command.DeletePrincipalCommand; |
| import org.apache.kerby.kerberos.tool.kadmin.command.GetPrincipalCommand; |
| import org.apache.kerby.kerberos.tool.kadmin.command.KadminCommand; |
| import org.apache.kerby.kerberos.tool.kadmin.command.KeytabAddCommand; |
| import org.apache.kerby.kerberos.tool.kadmin.command.ListPrincipalCommand; |
| import org.apache.kerby.kerberos.tool.kadmin.command.RenamePrincipalCommand; |
| import org.apache.kerby.util.OSUtil; |
| import org.jline.reader.Completer; |
| import org.jline.reader.LineReader; |
| import org.jline.reader.LineReaderBuilder; |
| import org.jline.reader.impl.completer.StringsCompleter; |
| import org.jline.terminal.Terminal; |
| import org.jline.terminal.TerminalBuilder; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import javax.security.auth.Subject; |
| import javax.security.auth.kerberos.KerberosPrincipal; |
| import javax.security.auth.login.LoginException; |
| import java.io.File; |
| import java.io.IOException; |
| import java.security.Principal; |
| import java.util.Map; |
| import java.util.Set; |
| |
| public class AdminLocalTool { |
| private static final Logger LOG = LoggerFactory.getLogger(AdminLocalTool.class); |
| private static File confDir; |
| |
| private static final String PROMPT = "admin.local"; |
| private static final String USAGE = (OSUtil.isWindows() |
| ? "Usage: bin\\admin-local.cmd" : "Usage: sh bin/admin-local.sh") |
| + " <conf-dir> <-c cache_name>|<-k keytab>\n" |
| + "\tExample:\n" |
| + "\t\t" |
| + (OSUtil.isWindows() |
| ? "bin\\admin-local.cmd" : "sh bin/admin-local.sh") |
| + " conf -k admin.keytab\n"; |
| |
| private static void printUsage(String error) { |
| System.err.println(error + "\n"); |
| System.err.println(USAGE); |
| System.exit(-1); |
| } |
| |
| 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" |
| + "change_password, cpw\n" |
| + " Change password\n" |
| + "get_principal, getprinc\n" |
| + " Get principal\n" |
| + "list_principals, listprincs\n" |
| + " List principals\n" |
| + "ktadd, xst\n" |
| + " Add entry(s) to a keytab\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" |
| + "deploy_keytabs, depkeytabs\n" |
| + " Deploy keytabs\n" |
| + "deploy_https, dephttps\n" |
| + " Deploy https\n"; |
| |
| private static void execute(LocalKadmin kadmin, LocalHadmin hadmin, String input) throws HasException { |
| // Omit the leading and trailing whitespace. |
| input = input.trim(); |
| if (input.startsWith("cmd")) { |
| System.out.println(LEGAL_COMMANDS); |
| return; |
| } |
| |
| String[] items = input.split("\\s+"); |
| String cmd = items[0]; |
| HadminCommand hadminExecutor = null; |
| KadminCommand kadminExecutor = null; |
| if (cmd.startsWith("add_principal") |
| || cmd.startsWith("addprinc")) { |
| kadminExecutor = new AddPrincipalCommand(kadmin); |
| } else if (cmd.startsWith("delete_principal") |
| || cmd.startsWith("delprinc")) { |
| kadminExecutor = new DeletePrincipalCommand(kadmin); |
| } else if (cmd.startsWith("rename_principal") |
| || cmd.startsWith("renprinc")) { |
| kadminExecutor = new RenamePrincipalCommand(kadmin); |
| } else if (cmd.startsWith("change_password") |
| || cmd.startsWith("cpw")) { |
| kadminExecutor = new ChangePasswordCommand(kadmin); |
| } else if (cmd.startsWith("list_principals") |
| || cmd.startsWith("listprincs")) { |
| kadminExecutor = new ListPrincipalCommand(kadmin); |
| } else if (cmd.startsWith("get_principal") |
| || cmd.startsWith("getprinc")) { |
| kadminExecutor = new GetPrincipalCommand(kadmin); |
| } else if (cmd.startsWith("ktadd") |
| || cmd.startsWith("xst")) { |
| kadminExecutor = new KeytabAddCommand(kadmin); |
| } else if (cmd.startsWith("get_hostroles") |
| || cmd.startsWith("hostroles")) { |
| hadminExecutor = new GetHostRolesCommand(hadmin); |
| } else if (cmd.startsWith("create_principals") |
| || cmd.startsWith("creprincs")) { |
| hadminExecutor = new AddPrincipalsCommand(hadmin); |
| } else if (cmd.startsWith("export_keytabs") |
| || cmd.startsWith("expkeytabs")) { |
| hadminExecutor = new ExportKeytabsCommand(hadmin); |
| } else if (cmd.startsWith("enable_configure") |
| || cmd.startsWith("enable")) { |
| hadminExecutor = new EnableConfigureCommand(hadmin); |
| } else if (cmd.startsWith("disable_configure") |
| || cmd.startsWith("disable")) { |
| hadminExecutor = new DisableConfigureCommand(hadmin); |
| } else if (cmd.startsWith("deploy_keytabs") |
| || cmd.startsWith("depkeytabs")) { |
| hadminExecutor = new AddPrincipalsAndDeployKeytabsCommand(hadmin); |
| } else if (cmd.startsWith("deploy_https") |
| || cmd.startsWith("dephttps")) { |
| hadminExecutor = new DeployHTTPSCertsCommand(hadmin); |
| } else { |
| System.out.println(LEGAL_COMMANDS); |
| return; |
| } |
| if (kadminExecutor != null) { |
| kadminExecutor.execute(input); |
| } else if (hadminExecutor != null) { |
| hadminExecutor.execute(items); |
| } |
| } |
| |
| private static File getConfDir(String[] args) { |
| String envDir; |
| confDir = new File(args[0]); |
| if (confDir == null || !confDir.exists()) { |
| try { |
| Map<String, String> mapEnv = System.getenv(); |
| envDir = mapEnv.get("KRB5_KDC_DIR"); |
| } catch (SecurityException e) { |
| envDir = null; |
| } |
| if (envDir != null) { |
| confDir = new File(envDir); |
| } else { |
| confDir = new File("/etc/kerby/"); // for Linux. TODO: fix for Win etc. |
| } |
| |
| if (!confDir.exists()) { |
| throw new RuntimeException("Can not locate KDC backend directory " |
| + confDir.getAbsolutePath()); |
| } |
| } |
| LOG.info("Conf dir:" + confDir.getAbsolutePath()); |
| return confDir; |
| } |
| |
| public static void main(String[] args) { |
| |
| if (args.length < 2) { |
| System.err.println(USAGE); |
| return; |
| } |
| |
| LocalKadmin kadmin; |
| try { |
| kadmin = new LocalKadminImpl(getConfDir(args)); |
| } catch (KrbException e) { |
| System.err.println("Failed to init Kadmin due to " + e.getMessage()); |
| return; |
| } |
| |
| LocalHadmin hadmin; |
| try { |
| hadmin = new LocalHadmin(getConfDir(args)); |
| } catch (KrbException e) { |
| System.err.println("Failed to init Hadmin due to " + e.getMessage()); |
| return; |
| } |
| |
| try { |
| Krb5Conf krb5Conf = new Krb5Conf(confDir, kadmin.getKdcConfig()); |
| krb5Conf.initKrb5conf(); |
| } catch (IOException e) { |
| System.err.println("Failed to make krb5.conf." + e.getMessage()); |
| } |
| |
| String kadminPrincipal = kadmin.getKadminPrincipal(); |
| |
| |
| KOptions kOptions = ToolUtil.parseOptions(args, 1, args.length - 1); |
| if (kOptions == null) { |
| System.err.println(USAGE); |
| return; |
| } |
| |
| Subject subject = null; |
| if (kOptions.contains(KadminOption.CCACHE)) { |
| File ccFile = kOptions.getFileOption(KadminOption.CCACHE); |
| if (ccFile == null || !ccFile.exists()) { |
| printUsage("Need the valid credentials cache file."); |
| return; |
| } |
| try { |
| subject = AuthUtil.loginUsingTicketCache(kadminPrincipal, ccFile); |
| } catch (LoginException e) { |
| System.err.println("Could not login with: " + kadminPrincipal |
| + e.getMessage()); |
| return; |
| } |
| } else if (kOptions.contains(KadminOption.K)) { |
| File keyTabFile = new File(kOptions.getStringOption(KadminOption.K)); |
| if (keyTabFile == null || !keyTabFile.exists()) { |
| printUsage("Need the valid keytab file."); |
| return; |
| } |
| try { |
| subject = AuthUtil.loginUsingKeytab(kadminPrincipal, keyTabFile); |
| } catch (LoginException e) { |
| System.err.println("Could not login with: " + kadminPrincipal |
| + e.getMessage()); |
| return; |
| } |
| } else { |
| printUsage("No credentials cache file or keytab file for authentication."); |
| } |
| if (subject != null) { |
| Principal adminPrincipal = new KerberosPrincipal(kadminPrincipal); |
| Set<Principal> princSet = subject.getPrincipals(); |
| if (princSet == null || princSet.isEmpty()) { |
| printUsage("The principals in subject is empty."); |
| return; |
| } |
| if (princSet.contains(adminPrincipal)) { |
| System.out.println("Login successful for user: " + kadminPrincipal); |
| } else { |
| printUsage("Login failure for " + kadminPrincipal); |
| return; |
| } |
| } else { |
| printUsage("The subject is null, login failure for " + kadminPrincipal); |
| return; |
| } |
| |
| System.out.println("enter \"cmd\" to see legal commands."); |
| |
| Completer completer = new StringsCompleter("add_principal", |
| "delete_principal", "rename_principal", "change_password", "list_principals", |
| "get_principal", "ktadd", "get_hostroles", "export_keytabs", "add_principals", |
| "enable_configure", "disable_configure", "deploy_keytabs", "deploy_https"); |
| |
| Terminal terminal = null; |
| try { |
| terminal = TerminalBuilder.terminal(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| LineReader lineReader = LineReaderBuilder.builder().completer(completer).terminal(terminal).build(); |
| |
| while (true) { |
| try { |
| String line = lineReader.readLine(PROMPT + ": "); |
| if ("quit".equals(line) || "exit".equals(line) || "q".equals(line)) { |
| break; |
| } |
| execute(kadmin, hadmin, line); |
| } catch (HasException e) { |
| System.err.println(e.getMessage()); |
| } |
| } |
| } |
| } |