You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by tf...@apache.org on 2017/05/19 00:13:23 UTC

[02/50] [abbrv] lucene-solr:jira/solr-10233: SOLR-8440: Support for enabling basic authentication using bin/solr|bin/solr.cmd

SOLR-8440: Support for enabling basic authentication using bin/solr|bin/solr.cmd


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/9be68cc3
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/9be68cc3
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/9be68cc3

Branch: refs/heads/jira/solr-10233
Commit: 9be68cc3079a320d323e46c570de3e9e883052ed
Parents: 9c6279d
Author: Ishan Chattopadhyaya <is...@apache.org>
Authored: Mon May 15 22:06:26 2017 +0530
Committer: Ishan Chattopadhyaya <is...@apache.org>
Committed: Mon May 15 22:06:26 2017 +0530

----------------------------------------------------------------------
 solr/bin/solr                                   | 164 +++++++++-
 solr/bin/solr.cmd                               |  72 ++++-
 .../src/java/org/apache/solr/util/SolrCLI.java  | 323 ++++++++++---------
 3 files changed, 400 insertions(+), 159 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9be68cc3/solr/bin/solr
----------------------------------------------------------------------
diff --git a/solr/bin/solr b/solr/bin/solr
index cae386f..14d3f59 100755
--- a/solr/bin/solr
+++ b/solr/bin/solr
@@ -294,7 +294,7 @@ function print_usage() {
   if [ -z "$CMD" ]; then
     echo ""
     echo "Usage: solr COMMAND OPTIONS"
-    echo "       where COMMAND is one of: start, stop, restart, status, healthcheck, create, create_core, create_collection, delete, version, zk"
+    echo "       where COMMAND is one of: start, stop, restart, status, healthcheck, create, create_core, create_collection, delete, version, zk, auth"
     echo ""
     echo "  Standalone server example (start Solr running in the background on port 8984):"
     echo ""
@@ -544,6 +544,35 @@ function print_usage() {
     echo "             <path>: The Zookeeper path to create. Leading slash is assumed if not present."
     echo "                     Intermediate nodes are created as needed if not present."
     echo ""
+  elif [ "$CMD" == "auth" ]; then
+    echo ""
+    echo "Usage: solr auth enable [-type basicAuth] -credentials user:pass [-blockUnknown <true|false>] [-updateIncludeFileOnly <true|false>]"
+    echo "       solr auth enable [-type basicAuth] -prompt <true|false> [-blockUnknown <true|false>] [-updateIncludeFileOnly <true|false>]"
+    echo "       solr auth disable [-updateIncludeFileOnly <true|false>]"
+    echo ""
+    echo "  -type <type>                           The authentication mechanism to enable. Defaults to 'basicAuth'."
+    echo ""
+    echo "  -credentials <user:pass>               The username and password of the initial user"
+    echo "                                         Note: only one of -prompt or -credentials must be provided"
+    echo ""
+    echo "  -prompt <true|false>                   Prompts the user to provide the credentials"
+    echo "                                         Note: only one of -prompt or -credentials must be provided"
+    echo ""
+    echo "  -blockUnknown <true|false>             When true, this blocks out access to unauthenticated users. When not provided,"
+    echo "                                         this defaults to false (i.e. unauthenticated users can access all endpoints, except the"
+    echo "                                         operations like collection-edit, security-edit, core-admin-edit etc.). Check the reference"
+    echo "                                         guide for Basic Authentication for more details."
+    echo ""
+    echo "  -updateIncludeFileOnly <true|false>    Only update the solr.in.sh or solr.in.cmd file, and skip actual enabling/disabling"
+    echo "                                         authentication (i.e. don't update security.json)"
+    echo ""
+    echo "  -z zkHost                              Zookeeper connection string"
+    echo ""
+    echo "  -d <dir>                               Specify the Solr server directory"
+    echo ""
+    echo "  -s <dir>                               Specify the Solr home directory. This is where any credentials or authentication"
+    echo "                                         configuration files (e.g. basicAuth.conf) would be placed."
+    echo ""
   fi
 } # end print_usage
 
@@ -1187,19 +1216,130 @@ if [[ "$SCRIPT_CMD" == "zk" ]]; then
 fi
 
 if [[ "$SCRIPT_CMD" == "auth" ]]; then
-    if [ -z "$AUTH_PORT" ]; then
-      for ID in `ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r`
-        do
-          port=`jetty_port "$ID"`
-          if [ "$port" != "" ]; then
-            AUTH_PORT=$port
+  declare -a AUTH_PARAMS
+  if [ $# -gt 0 ]; then
+    while true; do
+      case "$1" in
+        enable|disable)
+            AUTH_OP=$1
+            AUTH_PARAMS=("${AUTH_PARAMS[@]}" "$AUTH_OP")
+            shift
+        ;;
+        -z|-zkhost|zkHost)
+            ZK_HOST="$2"
+            AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-zkHost" "$ZK_HOST")
+            shift 2
+        ;;
+        -t|-type)
+            AUTH_TYPE="$2"
+            AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-type" "$AUTH_TYPE")
+            shift 2
+        ;;
+        -credentials)
+            AUTH_CREDENTIALS="$2"
+            AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-credentials" "$AUTH_CREDENTIALS")
+            shift 2
+        ;;
+        -solrIncludeFile)
+            SOLR_INCLUDE="$2"
+            shift 2
+        ;;
+        -prompt)
+            AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-prompt" "$2")
+            shift
+        ;;
+        -blockUnknown)
+            AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-blockUnknown" "$2")
+            shift
             break
-          fi
-        done
+        ;;
+        -updateIncludeFileOnly)
+            AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-updateIncludeFileOnly" "$2")
+            shift
+            break
+        ;;
+        -d|-dir)
+            if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+              print_usage "$SCRIPT_CMD" "Server directory is required when using the $1 option!"
+              exit 1
+            fi
+
+            if [[ "$2" == "." || "$2" == "./" || "$2" == ".." || "$2" == "../" ]]; then
+              SOLR_SERVER_DIR="$(pwd)/$2"
+            else
+              # see if the arg value is relative to the tip vs full path
+              if [[ "$2" != /* ]] && [[ -d "$SOLR_TIP/$2" ]]; then
+                SOLR_SERVER_DIR="$SOLR_TIP/$2"
+              else
+                SOLR_SERVER_DIR="$2"
+              fi
+            fi
+            # resolve it to an absolute path
+            SOLR_SERVER_DIR="$(cd "$SOLR_SERVER_DIR"; pwd)"
+            shift 2
+        ;;
+        -s|-solr.home)
+            if [[ -z "$2" || "${2:0:1}" == "-" ]]; then
+              print_usage "$SCRIPT_CMD" "Solr home directory is required when using the $1 option!"
+              exit 1
+            fi
+
+            SOLR_HOME="$2"
+            shift 2
+        ;;
+        -help|-usage|-h)
+            print_usage "$SCRIPT_CMD"
+            exit 0
+        ;;
+        --)
+            shift
+            break
+        ;;
+        *)
+            shift
+            break
+        ;;
+      esac
+    done
+  fi
+
+  if [ -z "$SOLR_SERVER_DIR" ]; then
+    SOLR_SERVER_DIR="$DEFAULT_SERVER_DIR"
+  fi
+  if [ ! -e "$SOLR_SERVER_DIR" ]; then
+    echo -e "\nSolr server directory $SOLR_SERVER_DIR not found!\n"
+    exit 1
+  fi
+  if [ -z "$SOLR_HOME" ]; then
+    SOLR_HOME="$SOLR_SERVER_DIR/solr"
+  else
+    if [[ $SOLR_HOME != /* ]] && [[ -d "$SOLR_SERVER_DIR/$SOLR_HOME" ]]; then
+      SOLR_HOME="$SOLR_SERVER_DIR/$SOLR_HOME"
+      SOLR_PID_DIR="$SOLR_HOME"
+    elif [[ $SOLR_HOME != /* ]] && [[ -d "`pwd`/$SOLR_HOME" ]]; then
+      SOLR_HOME="$(pwd)/$SOLR_HOME"
     fi
-    solr_include_file=$SOLR_INCLUDE
-    run_tool auth "$@" -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$AUTH_PORT/solr" -solrIncludeFile "$solr_include_file"
-    exit $?
+  fi
+
+  if [ -z "$AUTH_OP" ]; then
+    print_usage "$SCRIPT_CMD"
+    exit 0
+  fi
+
+  AUTH_PARAMS=("${AUTH_PARAMS[@]}" "-solrIncludeFile" "$SOLR_INCLUDE")
+
+  if [ -z "$AUTH_PORT" ]; then
+    for ID in `ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r`
+      do
+        port=`jetty_port "$ID"`
+        if [ "$port" != "" ]; then
+          AUTH_PORT=$port
+          break
+        fi
+      done
+  fi
+  run_tool auth ${AUTH_PARAMS[@]} -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$AUTH_PORT/solr" -authConfDir "$SOLR_HOME"
+  exit $?
 fi
 
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9be68cc3/solr/bin/solr.cmd
----------------------------------------------------------------------
diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd
index d181f8d..1d093b9 100644
--- a/solr/bin/solr.cmd
+++ b/solr/bin/solr.cmd
@@ -276,7 +276,7 @@ goto done
 :script_usage
 @echo.
 @echo Usage: solr COMMAND OPTIONS
-@echo        where COMMAND is one of: start, stop, restart, healthcheck, create, create_core, create_collection, delete, version, zk
+@echo        where COMMAND is one of: start, stop, restart, healthcheck, create, create_core, create_collection, delete, version, zk, auth
 @echo.
 @echo   Standalone server example (start Solr running in the background on port 8984):
 @echo.
@@ -554,6 +554,35 @@ IF "%ZK_FULL%"=="true" (
 )
 goto done
 
+:auth_usage
+echo Usage: solr auth enable [-type basicAuth] -credentials user:pass [-blockUnknown ^<true|false^>] [-updateIncludeFileOnly ^<true|false^>]
+echo        solr auth enable [-type basicAuth] -prompt ^<true|false^> [-blockUnknown ^<true|false^>] [-updateIncludeFileOnly ^<true|false^>]
+echo        solr auth disable [-updateIncludeFileOnly ^<true|false^>]
+echo
+echo   -type ^<type^>                 The authentication mechanism to enable. Defaults to 'basicAuth'.
+echo
+echo   -credentials ^<user:pass^>     The username and password of the initial user
+echo                                Note: only one of -prompt or -credentials must be provided
+echo
+echo   -prompt ^<true|false^>         Prompts the user to provide the credentials
+echo                                Note: only one of -prompt or -credentials must be provided
+echo
+echo   -blockUnknown ^<true|false^>   When true, this blocks out access to unauthenticated users. When not provided,
+echo                                this defaults to false (i.e. unauthenticated users can access all endpoints, except the
+echo                                operations like collection-edit, security-edit, core-admin-edit etc.). Check the reference
+echo                                guide for Basic Authentication for more details.
+echo
+echo   -updateIncludeFileOnly ^<true|false^>    Only update the solr.in.sh or solr.in.cmd file, and skip actual enabling/disabling"
+echo                                          authentication (i.e. don't update security.json)"
+echo
+echo   -z zkHost                    Zookeeper connection string
+echo
+echo   -d <dir>                     Specify the Solr server directory"
+echo 
+echo   -s <dir>                     Specify the Solr home directory. This is where any credentials or authentication"
+echo                                configuration files (e.g. basicAuth.conf) would be placed."
+echo
+goto done
 
 REM Really basic command-line arg parsing
 :parse_args
@@ -1648,6 +1677,44 @@ goto done
 
  
 :run_auth
+IF "%1"=="-help" goto usage
+IF "%1"=="-usage" goto usage
+
+REM Options parsing.
+REM Note: With the following technique of parsing, it is not possible
+REM       to have an option without a value.
+set "AUTH_PARAMS=%1"
+set "option="
+for %%a in (%*) do (
+   if not defined option (
+      set arg=%%a
+      if "!arg:~0,1!" equ "-" set "option=!arg!"
+   ) else (
+      set "option!option!=%%a"
+      if "!option!" equ "-d" set "SOLR_SERVER_DIR=%%a"
+      if "!option!" equ "-s" set "SOLR_HOME=%%a"
+      if not "!option!" equ "-s" if not "!option!" equ "-d" (
+        set "AUTH_PARAMS=!AUTH_PARAMS! !option! %%a"
+      )
+      set "option="
+   )
+)
+IF "%SOLR_SERVER_DIR%"=="" set "SOLR_SERVER_DIR=%DEFAULT_SERVER_DIR%"
+IF NOT EXIST "%SOLR_SERVER_DIR%" (
+  set "SCRIPT_ERROR=Solr server directory %SOLR_SERVER_DIR% not found!"
+  goto err
+)
+IF "%SOLR_HOME%"=="" set "SOLR_HOME=%SOLR_SERVER_DIR%\solr"
+IF EXIST "%cd%\%SOLR_HOME%" set "SOLR_HOME=%cd%\%SOLR_HOME%"
+IF NOT EXIST "%SOLR_HOME%\" (
+  IF EXIST "%SOLR_SERVER_DIR%\%SOLR_HOME%" (
+    set "SOLR_HOME=%SOLR_SERVER_DIR%\%SOLR_HOME%"
+  ) ELSE (
+    set "SCRIPT_ERROR=Solr home directory %SOLR_HOME% not found!"
+    goto err
+  )
+)
+
 if "!AUTH_PORT!"=="" (
   for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
     set SOME_SOLR_PORT=
@@ -1659,11 +1726,10 @@ if "!AUTH_PORT!"=="" (
     )
   )
 )
-for /f "tokens=1,* delims= " %%a in ("%*") do set auth_params=%%b
 "%JAVA%" %SOLR_SSL_OPTS% %AUTHC_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" ^
     -Dlog4j.configuration="file:%DEFAULT_SERVER_DIR%\scripts\cloud-scripts\log4j.properties" ^
     -classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
-    org.apache.solr.util.SolrCLI auth %auth_params% -solrIncludeFile "%SOLR_INCLUDE%" ^
+    org.apache.solr.util.SolrCLI auth %AUTH_PARAMS% -solrIncludeFile "%SOLR_INCLUDE%" -authConfDir "%SOLR_HOME%" ^
     -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!AUTH_PORT!/solr
 goto done
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/9be68cc3/solr/core/src/java/org/apache/solr/util/SolrCLI.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/SolrCLI.java b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
index 0fef03c..aedb9ed 100644
--- a/solr/core/src/java/org/apache/solr/util/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
@@ -3526,49 +3526,59 @@ public class SolrCLI {
     public Option[] getOptions() {
       return new Option[]{
           OptionBuilder
-              .withArgName("enable")
-              .withDescription("Enable authentication.")
-              .create("enable"),
-          OptionBuilder
-              .withArgName("disable")
-              .withDescription("Disable existing authentication.")
-              .create("disable"),
-          OptionBuilder
-              .withArgName("type")
-              .hasArg()
-              .withDescription("basicAuth")
-              .create("type"),
-          OptionBuilder
-              .withArgName("credentials")
-              .hasArg()
-              .withDescription("Credentials in the format username:password. Example: -credentials solr:SolrRocks")
-              .create("credentials"),
-          OptionBuilder
-              .withArgName("prompt")
-              .withDescription("Prompt for credentials. Use either -credentials or -prompt, not both")
-              .create("prompt"),              
-          OptionBuilder
-              .withArgName("blockUnknown")
-              .withDescription("Blocks all access for unknown users (requires authentication for all endpoints)")
-              .hasOptionalArg()
-              .create("blockUnknown"),
-          OptionBuilder
-              .withArgName("solrIncludeFile")
-              .hasArg()
-              .withDescription("The Solr include file which contains overridable environment variables for configuring Solr configurations")
-              .create("solrIncludeFile"),
-          OptionBuilder
-              .withArgName("solrUrl")
-              .hasArg()
-              .withDescription("Solr URL")
-              .create("solrUrl"),
+          .withArgName("type")
+          .hasArg()
+          .withDescription("The authentication mechanism to enable. Defaults to 'basicAuth'.")
+          .create("type"),
+          OptionBuilder
+          .withArgName("credentials")
+          .hasArg()
+          .withDescription("Credentials in the format username:password. Example: -credentials solr:SolrRocks")
+          .create("credentials"),
+          OptionBuilder
+          .withArgName("prompt")
+          .hasArg()
+          .withDescription("Prompts the user to provide the credentials. Use either -credentials or -prompt, not both")
+          .create("prompt"),
+          OptionBuilder
+          .withArgName("blockUnknown")
+          .withDescription("Blocks all access for unknown users (requires authentication for all endpoints)")
+          .hasArg()
+          .create("blockUnknown"),
+          OptionBuilder
+          .withArgName("solrIncludeFile")
+          .hasArg()
+          .withDescription("The Solr include file which contains overridable environment variables for configuring Solr configurations")
+          .create("solrIncludeFile"),
+          OptionBuilder
+          .withArgName("updateIncludeFileOnly")
+          .withDescription("Only update the solr.in.sh or solr.in.cmd file, and skip actual enabling/disabling"
+              + " authentication (i.e. don't update security.json)")
+          .hasArg()
+          .create("updateIncludeFileOnly"),
+          OptionBuilder
+          .withArgName("authConfDir")
+          .hasArg()
+          .isRequired()
+          .withDescription("This is where any authentication related configuration files, if any, would be placed.")
+          .create("authConfDir"),
+          OptionBuilder
+          .withArgName("solrUrl")
+          .hasArg()
+          .withDescription("Solr URL")
+          .create("solrUrl"),
+          OptionBuilder
+          .withArgName("zkHost")
+          .hasArg()
+          .withDescription("ZooKeeper host")
+          .create("zkHost"),
       };
     }
 
     @Override
     public int runTool(CommandLine cli) throws Exception {
-      if (cli.getOptions().length == 0 || cli.getArgs().length > 0 || cli.hasOption("h")) {
-        new HelpFormatter().printHelp("bin/solr auth [OPTIONS]", getToolOptions(this));
+      if (cli.getOptions().length == 0 || cli.getArgs().length == 0 || cli.getArgs().length > 1 || cli.hasOption("h")) {
+        new HelpFormatter().printHelp("bin/solr auth <enable|disable> [OPTIONS]", getToolOptions(this));
         return 1;
       }
 
@@ -3578,128 +3588,153 @@ public class SolrCLI {
         exit(1);
       }
 
-      if (cli.hasOption("enable") && cli.hasOption("disable")) {
-        System.out.println("You have specified both -enable and -disable. Only one should be provided.");
-        return 1;
-      }
-      if  (cli.hasOption("enable")) {
-        String zkHost = getZkHost(cli);
-        if (zkHost == null) {
-          System.out.println("ZK Host not found. Solr should be running in cloud mode");
-          exit(1);
-        }
+      String cmd = cli.getArgs()[0];
+      boolean prompt = Boolean.parseBoolean(cli.getOptionValue("prompt", "false"));
+      boolean updateIncludeFileOnly = Boolean.parseBoolean(cli.getOptionValue("updateIncludeFileOnly", "false"));
+      switch (cmd) {
+        case "enable":
+          if (!prompt && !cli.hasOption("credentials")) {
+            System.out.println("Option -credentials or -prompt is required with enable.");
+            new HelpFormatter().printHelp("bin/solr auth <enable|disable> [OPTIONS]", getToolOptions(this));
+            exit(1);
+          } else if (!prompt && (cli.getOptionValue("credentials") == null || !cli.getOptionValue("credentials").contains(":"))) {
+            System.out.println("Option -credentials is not in correct format.");
+            new HelpFormatter().printHelp("bin/solr auth <enable|disable> [OPTIONS]", getToolOptions(this));
+            exit(1);
+          }
 
-        
-        if (cli.hasOption("credentials") == false && cli.hasOption("prompt") == false) {
-          System.out.println("Option -credentials or -prompt is required with -enable.");
-          new HelpFormatter().printHelp("bin/solr auth [OPTIONS]", getToolOptions(this));
-          exit(1);
-        } else if (cli.hasOption("prompt") == false &&
-            (cli.getOptionValue("credentials") == null || !cli.getOptionValue("credentials").contains(":"))) {
-          System.out.println("Option -credentials is not in correct format.");
-          new HelpFormatter().printHelp("bin/solr auth [OPTIONS]", getToolOptions(this));
-          exit(1);
-        }
+          String zkHost = null;
 
-        String username, password;
-        if (cli.hasOption("credentials")) {
-          String credentials = cli.getOptionValue("credentials");
-          username = credentials.split(":")[0];
-          password = credentials.split(":")[1];
-        } else {
-          Console console = System.console();
-          username = console.readLine("Enter username: ");
-          password = new String(console.readPassword("Enter password: "));
-        }
-        // check if security is already enabled or not
-        try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
-          if (zkClient.exists("/security.json", true)) {
-            byte oldSecurityBytes[] = zkClient.getData("/security.json", null, null, true);
-            if (!"{}".equals(new String(oldSecurityBytes, StandardCharsets.UTF_8).trim())) {
-              System.out.println("Security is already enabled. You can disable it with 'bin/solr auth -disable'. Existing security.json: \n"
-                  + new String(oldSecurityBytes, StandardCharsets.UTF_8));
+          if (!updateIncludeFileOnly) {
+            try {
+              zkHost = getZkHost(cli);
+            } catch (Exception ex) {
+              if (cli.hasOption("zkHost")) {
+                System.out.println("Couldn't get ZooKeeper host. Please make sure that ZooKeeper is running and the correct zkHost has been passed in.");
+              } else {
+                System.out.println("Couldn't get ZooKeeper host. Please make sure Solr is running in cloud mode, or a zkHost has been passed in.");
+              }
+              exit(1);
+            }
+            if (zkHost == null) {
+              if (cli.hasOption("zkHost")) {
+                System.out.println("Couldn't get ZooKeeper host. Please make sure that ZooKeeper is running and the correct zkHost has been passed in.");
+              } else {
+                System.out.println("Couldn't get ZooKeeper host. Please make sure Solr is running in cloud mode, or a zkHost has been passed in.");
+              }
               exit(1);
             }
+
+            // check if security is already enabled or not
+            try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
+              if (zkClient.exists("/security.json", true)) {
+                byte oldSecurityBytes[] = zkClient.getData("/security.json", null, null, true);
+                if (!"{}".equals(new String(oldSecurityBytes, StandardCharsets.UTF_8).trim())) {
+                  System.out.println("Security is already enabled. You can disable it with 'bin/solr auth disable'. Existing security.json: \n"
+                      + new String(oldSecurityBytes, StandardCharsets.UTF_8));
+                  exit(1);
+                }
+              }
+            }
           }
-        }
 
-        boolean blockUnknown = cli.getOptionValue("blockUnknown") == null ?
-            cli.hasOption("blockUnknown"): Boolean.valueOf(cli.getOptionValue("blockUnknown"));
-
-            String securityJson = "{" +
-                "\n  \"authentication\":{" +
-                "\n   \"blockUnknown\": " + blockUnknown + "," +
-                "\n   \"class\":\"solr.BasicAuthPlugin\"," +
-                "\n   \"credentials\":{\""+username+"\":\"" + Sha256AuthenticationProvider.getSaltedHashedValue(password) + "\"}" +
-                "\n  }," +
-                "\n  \"authorization\":{" +
-                "\n   \"class\":\"solr.RuleBasedAuthorizationPlugin\"," +
-                "\n   \"permissions\":[" +
-                "\n {\"name\":\"security-edit\", \"role\":\"admin\"}," +
-                "\n {\"name\":\"collection-admin-edit\", \"role\":\"admin\"}," +
-                "\n {\"name\":\"core-admin-edit\", \"role\":\"admin\"}" +
-                "\n   ]," +
-                "\n   \"user-role\":{\""+username+"\":\"admin\"}" +
-                "\n  }" +
-                "\n}";
-            System.out.println("Uploading following security.json: " + securityJson);
+          String username, password;
+          if (cli.hasOption("credentials")) {
+            String credentials = cli.getOptionValue("credentials");
+            username = credentials.split(":")[0];
+            password = credentials.split(":")[1];
+          } else {
+            Console console = System.console();
+            username = console.readLine("Enter username: ");
+            password = new String(console.readPassword("Enter password: "));
+          }
 
+          boolean blockUnknown = Boolean.valueOf(cli.getOptionValue("blockUnknown", "false"));
+
+          String securityJson = "{" +
+              "\n  \"authentication\":{" +
+              "\n   \"blockUnknown\": " + blockUnknown + "," +
+              "\n   \"class\":\"solr.BasicAuthPlugin\"," +
+              "\n   \"credentials\":{\"" + username + "\":\"" + Sha256AuthenticationProvider.getSaltedHashedValue(password) + "\"}" +
+              "\n  }," +
+              "\n  \"authorization\":{" +
+              "\n   \"class\":\"solr.RuleBasedAuthorizationPlugin\"," +
+              "\n   \"permissions\":[" +
+              "\n {\"name\":\"security-edit\", \"role\":\"admin\"}," +
+              "\n {\"name\":\"collection-admin-edit\", \"role\":\"admin\"}," +
+              "\n {\"name\":\"core-admin-edit\", \"role\":\"admin\"}" +
+              "\n   ]," +
+              "\n   \"user-role\":{\"" + username + "\":\"admin\"}" +
+              "\n  }" +
+              "\n}";
+
+          if (!updateIncludeFileOnly) {
+            System.out.println("Uploading following security.json: " + securityJson);
             try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
               zkClient.setData("/security.json", securityJson.getBytes(StandardCharsets.UTF_8), true);
             }
+          }
 
-            String solrIncludeFilename = cli.getOptionValue("solrIncludeFile");
-            File includeFile = new File(solrIncludeFilename);
-            if (includeFile.exists() == false || includeFile.canWrite() == false) {
-              System.out.println("Solr include file " + solrIncludeFilename + " doesn't exist or is not writeable.");
-              printAuthEnablingInstructions(username, password);
-              System.exit(0);
-            }
-            File basicAuthConfFile = new File(includeFile.getParent() + File.separator + "basicAuth.conf");
-            
-            if (basicAuthConfFile.getParentFile().canWrite() == false) {
-              System.out.println("Cannot write to file: " + basicAuthConfFile.getAbsolutePath());
-              printAuthEnablingInstructions(username, password);
-              System.exit(0);
+          String solrIncludeFilename = cli.getOptionValue("solrIncludeFile");
+          File includeFile = new File(solrIncludeFilename);
+          if (includeFile.exists() == false || includeFile.canWrite() == false) {
+            System.out.println("Solr include file " + solrIncludeFilename + " doesn't exist or is not writeable.");
+            printAuthEnablingInstructions(username, password);
+            System.exit(0);
+          }
+          String authConfDir = cli.getOptionValue("authConfDir");
+          File basicAuthConfFile = new File(authConfDir + File.separator + "basicAuth.conf");
+
+          if (basicAuthConfFile.getParentFile().canWrite() == false) {
+            System.out.println("Cannot write to file: " + basicAuthConfFile.getAbsolutePath());
+            printAuthEnablingInstructions(username, password);
+            System.exit(0);
+          }
+
+          FileUtils.writeStringToFile(basicAuthConfFile,
+              "httpBasicAuthUser=" + username + "\nhttpBasicAuthPassword=" + password, StandardCharsets.UTF_8);
+
+          // update the solr.in.sh file to contain the necessary authentication lines
+          updateIncludeFileEnableAuth(includeFile, basicAuthConfFile.getAbsolutePath());
+          return 0;
+
+        case "disable":
+          if (!updateIncludeFileOnly) {
+            zkHost = getZkHost(cli);
+            if (zkHost == null) {
+              stdout.print("ZK Host not found. Solr should be running in cloud mode");
+              exit(1);
             }
-            
-            FileUtils.writeStringToFile(basicAuthConfFile, 
-                "httpBasicAuthUser=" + username + "\nhttpBasicAuthPassword=" + password, StandardCharsets.UTF_8);
-
-            // update the solr.in.sh file to contain the necessary authentication lines
-            updateIncludeFileEnableAuth(includeFile, basicAuthConfFile.getAbsolutePath(), username, password);
-            return 0;
-      } else if (cli.hasOption("disable")) {
-        String zkHost = getZkHost(cli);
-        if (zkHost == null) {
-          stdout.print("ZK Host not found. Solr should be running in cloud mode");
-          exit(1);
-        }
 
-        System.out.println("Uploading following security.json: {}");
+            System.out.println("Uploading following security.json: {}");
 
-        try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
-          zkClient.setData("/security.json", "{}".getBytes(StandardCharsets.UTF_8), true);
-        }
+            try (SolrZkClient zkClient = new SolrZkClient(zkHost, 10000)) {
+              zkClient.setData("/security.json", "{}".getBytes(StandardCharsets.UTF_8), true);
+            }
+          }
 
-        String solrIncludeFilename = cli.getOptionValue("solrIncludeFile");
-        File includeFile = new File(solrIncludeFilename);
-        if (includeFile.exists() == false || includeFile.canWrite() == false) {
-          System.out.println("Solr include file " + solrIncludeFilename + " doesn't exist or is not writeable.");
-          System.out.println("Security has been disabled. Please remove any SOLR_AUTH_TYPE or SOLR_AUTHENTICATION_OPTS configuration from solr.in.sh/solr.in.cmd.\n");
-          System.exit(0);
-        }
+          solrIncludeFilename = cli.getOptionValue("solrIncludeFile");
+          includeFile = new File(solrIncludeFilename);
+          if (!includeFile.exists() || !includeFile.canWrite()) {
+            System.out.println("Solr include file " + solrIncludeFilename + " doesn't exist or is not writeable.");
+            System.out.println("Security has been disabled. Please remove any SOLR_AUTH_TYPE or SOLR_AUTHENTICATION_OPTS configuration from solr.in.sh/solr.in.cmd.\n");
+            System.exit(0);
+          }
 
-        // update the solr.in.sh file to comment out the necessary authentication lines
-        updateIncludeFileDisableAuth(includeFile);
-        return 0;
+          // update the solr.in.sh file to comment out the necessary authentication lines
+          updateIncludeFileDisableAuth(includeFile);
+          return 0;
+
+        default:
+          System.out.println("Valid auth commands are: enable, disable");
+          exit(1);
       }
 
-      System.out.println("Options not understood (should be -enable or -disable).");
-      new HelpFormatter().printHelp("bin/solr auth [OPTIONS]", getToolOptions(this));
+      System.out.println("Options not understood.");
+      new HelpFormatter().printHelp("bin/solr auth <enable|disable> [OPTIONS]", getToolOptions(this));
       return 1;
     }
-    
+
     private void printAuthEnablingInstructions(String username, String password) {
       if (SystemUtils.IS_OS_WINDOWS) {
         System.out.println("\nAdd the following lines to the solr.in.cmd file so that the solr.cmd script can use subsequently.\n");
@@ -3708,11 +3743,11 @@ public class SolrCLI {
       } else {
         System.out.println("\nAdd the following lines to the solr.in.sh file so that the ./solr script can use subsequently.\n");
         System.out.println("SOLR_AUTH_TYPE=\"basic\"\n"
-            + "SOLR_AUTHENTICATION_OPTS=\"-DbasicAuth=" + username + ":" + password + "\"\n");
+            + "SOLR_AUTHENTICATION_OPTS=\"-Dbasicauth=" + username + ":" + password + "\"\n");
       }
     }
 
-    private void updateIncludeFileEnableAuth(File includeFile, String basicAuthConfFile, String username, String password) throws IOException {
+    private void updateIncludeFileEnableAuth(File includeFile, String basicAuthConfFile) throws IOException {
       List<String> includeFileLines = FileUtils.readLines(includeFile, StandardCharsets.UTF_8);
       for (int i=0; i<includeFileLines.size(); i++) {
         String line = includeFileLines.get(i);
@@ -3738,7 +3773,7 @@ public class SolrCLI {
 
       System.out.println("Written out credentials file: " + basicAuthConfFile + ", updated Solr include file: " + includeFile.getAbsolutePath() + ".");
     }
-    
+
     private void updateIncludeFileDisableAuth(File includeFile) throws IOException {
       List<String> includeFileLines = FileUtils.readLines(includeFile, StandardCharsets.UTF_8);
       boolean hasChanged = false;
@@ -3762,7 +3797,7 @@ public class SolrCLI {
     @Override
     protected void runImpl(CommandLine cli) throws Exception {}
   }
-  
+
   public static class UtilsTool extends ToolBase {
     private Path serverPath;
     private Path logsPath;