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

This commit is contained in:
Ishan Chattopadhyaya 2017-05-15 22:06:26 +05:30
parent 9c6279d439
commit 9be68cc307
3 changed files with 395 additions and 154 deletions

View File

@ -294,7 +294,7 @@ function print_usage() {
if [ -z "$CMD" ]; then if [ -z "$CMD" ]; then
echo "" echo ""
echo "Usage: solr COMMAND OPTIONS" 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 ""
echo " Standalone server example (start Solr running in the background on port 8984):" echo " Standalone server example (start Solr running in the background on port 8984):"
echo "" echo ""
@ -544,6 +544,35 @@ function print_usage() {
echo " <path>: The Zookeeper path to create. Leading slash is assumed if not present." 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 " Intermediate nodes are created as needed if not present."
echo "" 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 fi
} # end print_usage } # end print_usage
@ -1187,19 +1216,130 @@ if [[ "$SCRIPT_CMD" == "zk" ]]; then
fi fi
if [[ "$SCRIPT_CMD" == "auth" ]]; then if [[ "$SCRIPT_CMD" == "auth" ]]; then
if [ -z "$AUTH_PORT" ]; then declare -a AUTH_PARAMS
for ID in `ps auxww | grep java | grep start\.jar | awk '{print $2}' | sort -r` if [ $# -gt 0 ]; then
do while true; do
port=`jetty_port "$ID"` case "$1" in
if [ "$port" != "" ]; then enable|disable)
AUTH_PORT=$port 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 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 fi
solr_include_file=$SOLR_INCLUDE fi
run_tool auth "$@" -solrUrl "$SOLR_URL_SCHEME://$SOLR_TOOL_HOST:$AUTH_PORT/solr" -solrIncludeFile "$solr_include_file"
exit $? 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 fi

View File

@ -276,7 +276,7 @@ goto done
:script_usage :script_usage
@echo. @echo.
@echo Usage: solr COMMAND OPTIONS @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.
@echo Standalone server example (start Solr running in the background on port 8984): @echo Standalone server example (start Solr running in the background on port 8984):
@echo. @echo.
@ -554,6 +554,35 @@ IF "%ZK_FULL%"=="true" (
) )
goto done 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 REM Really basic command-line arg parsing
:parse_args :parse_args
@ -1648,6 +1677,44 @@ goto done
:run_auth :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!"=="" ( if "!AUTH_PORT!"=="" (
for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do ( for /f "usebackq" %%i in (`dir /b "%SOLR_TIP%\bin" ^| findstr /i "^solr-.*\.port$"`) do (
set SOME_SOLR_PORT= 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%" ^ "%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" ^ -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\*" ^ -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 -solrUrl !SOLR_URL_SCHEME!://%SOLR_TOOL_HOST%:!AUTH_PORT!/solr
goto done goto done

View File

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