opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentConstants.java
@@ -375,15 +375,15 @@ /** Value for the restart option long form. */ public static final String OPTION_LONG_RESTART = "restart"; /** The value for the hidden testonly argument. */ public static final String OPTION_LONG_TESTONLY_ARGUMENT = "testOnly"; /** The value for the backend type long option. */ public static final String OPTION_LONG_BACKEND_TYPE = "backendType"; /** The value for the backend type short option. */ public static final Character OPTION_SHORT_BACKEND_TYPE = 't'; /** The value to use to read from stdin or write to stdout. */ public static final String USE_SYSTEM_STREAM_TOKEN = "-"; /** Prevent instantiation. */ private ArgumentConstants() { } opendj-cli/src/main/java/com/forgerock/opendj/cli/CommonArguments.java
@@ -632,6 +632,20 @@ } /** * Returns the "-S, --scriptFriendly" boolean argument used in the sdk toolkit. * * @return The "-S, --scriptFriendly" argument. * @throws ArgumentException * If there is a problem with any of the parameters used to create this argument. */ public static BooleanArgument scriptFriendlySdkArgument() throws ArgumentException { return BooleanArgument.builder("scriptFriendly") .shortIdentifier('S') .description(INFO_DESCRIPTION_SCRIPT_FRIENDLY.get()) .buildArgument(); } /** * Returns the "LDAP port" integer argument. * * @param defaultLdapPort opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AddRate.java
@@ -397,8 +397,10 @@ int run(final String[] args) { // Create the command-line argument parser for use with this program. final LocalizableMessage toolDescription = INFO_ADDRATE_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser(AddRate.class.getName(), toolDescription, false, true, 1, 1, "template-file-path"); final ArgumentParser argParser = LDAPToolArgumentParser.builder(AddRate.class.getName()) .toolDescription(toolDescription) .trailingArguments(1, "template-file-path") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_ADDRATE.get()); argParser.setDocToolDescriptionSupplement(SUPPLEMENT_DESCRIPTION_RATE_TOOLS.get()); @@ -533,10 +535,7 @@ verbose = verboseArgument(); argParser.addArgument(verbose); scriptFriendly = BooleanArgument.builder("scriptFriendly") .shortIdentifier('S') .description(INFO_DESCRIPTION_SCRIPT_FRIENDLY.get()) .buildAndAddToParser(argParser); scriptFriendly = scriptFriendlySdkArgument(); argParser.addArgument(scriptFriendly); } } opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/AuthRate.java
@@ -375,9 +375,10 @@ int run(final String[] args) { // Create the command-line argument parser for use with this program. final LocalizableMessage toolDescription = INFO_AUTHRATE_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser(AuthRate.class.getName(), toolDescription, false, true, 0, 0, "[filter format string] [attributes ...]"); final ArgumentParser argParser = LDAPToolArgumentParser.builder(AuthRate.class.getName()) .toolDescription(toolDescription) .trailingArguments("[filter format string] [attributes ...]") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_AUTHRATE.get()); argParser.setDocToolDescriptionSupplement(SUPPLEMENT_DESCRIPTION_RATE_TOOLS.get()); @@ -446,11 +447,8 @@ verbose = verboseArgument(); argParser.addArgument(verbose); scriptFriendly = BooleanArgument.builder("scriptFriendly") .shortIdentifier('S') .description(INFO_DESCRIPTION_SCRIPT_FRIENDLY.get()) .buildAndAddToParser(argParser); scriptFriendly = scriptFriendlySdkArgument(); argParser.addArgument(scriptFriendly); } catch (final ArgumentException ae) { final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); errPrintln(message); opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPCompare.java
@@ -18,13 +18,18 @@ import static com.forgerock.opendj.cli.ArgumentConstants.*; import static com.forgerock.opendj.cli.ToolVersionHandler.newSdkVersionHandler; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolParamException; import static com.forgerock.opendj.ldap.tools.ToolsMessages.*; import static com.forgerock.opendj.cli.Utils.filterExitCode; import static com.forgerock.opendj.cli.Utils.readBytesFromFile; import static com.forgerock.opendj.ldap.tools.Utils.addControlsToRequest; import static com.forgerock.opendj.ldap.tools.Utils.printErrorMessage; import static com.forgerock.opendj.ldap.tools.Utils.printPasswordPolicyResults; import static com.forgerock.opendj.ldap.tools.Utils.readAssertionControl; import static com.forgerock.opendj.ldap.tools.Utils.ensureLdapProtocolVersionIsSupported; import static com.forgerock.opendj.ldap.tools.Utils.getConnection; import static com.forgerock.opendj.cli.CommonArguments.*; import static com.forgerock.opendj.ldap.tools.Utils.readControls; import static org.forgerock.util.Utils.closeSilently; import java.io.BufferedReader; @@ -34,26 +39,20 @@ import java.io.InputStreamReader; import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizedIllegalArgumentException; import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.Connection; import org.forgerock.opendj.ldap.ConnectionFactory; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.Filter; import org.forgerock.opendj.ldap.LdapException; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.controls.AssertionRequestControl; import org.forgerock.opendj.ldap.controls.Control; import org.forgerock.opendj.ldap.controls.ProxiedAuthV2RequestControl; import org.forgerock.opendj.ldap.requests.BindRequest; import org.forgerock.opendj.ldap.requests.CompareRequest; import org.forgerock.opendj.ldap.requests.Requests; import org.forgerock.opendj.ldap.responses.Result; import com.forgerock.opendj.cli.ArgumentException; import com.forgerock.opendj.cli.ArgumentParser; import com.forgerock.opendj.cli.BooleanArgument; import com.forgerock.opendj.cli.ConnectionFactoryProvider; import com.forgerock.opendj.cli.ConsoleApplication; @@ -69,7 +68,14 @@ * The command-line arguments provided to this program. */ public static void main(final String[] args) { final int retCode = new LDAPCompare().run(args); final LDAPCompare ldapCompare = new LDAPCompare(); int retCode; try { retCode = ldapCompare.run(args); } catch (final LDAPToolException e) { e.printErrorMessage(ldapCompare); retCode = e.getResultCode(); } System.exit(filterExitCode(retCode)); } @@ -100,50 +106,40 @@ } private int executeCompare(final CompareRequest request, final Connection connection) { println(INFO_PROCESSING_COMPARE_OPERATION.get(request.getAttributeDescription().toString(), request.getAssertionValueAsString(), request.getName().toString())); final String dnStr = request.getName().toString(); println(INFO_PROCESSING_COMPARE_OPERATION.get( request.getAttributeDescription().toString(), request.getAssertionValueAsString(), dnStr)); if (connection != null) { try { Result result = connection.compare(request); if (result.getResultCode() == ResultCode.COMPARE_FALSE) { println(INFO_COMPARE_OPERATION_RESULT_FALSE.get(request.getName().toString())); if (ResultCode.COMPARE_FALSE == result.getResultCode()) { println(INFO_COMPARE_OPERATION_RESULT_FALSE.get(dnStr)); } else { println(INFO_COMPARE_OPERATION_RESULT_TRUE.get(request.getName().toString())); println(INFO_COMPARE_OPERATION_RESULT_TRUE.get(dnStr)); } } catch (final LdapException ere) { final LocalizableMessage msg = INFO_OPERATION_FAILED.get("COMPARE"); errPrintln(msg); final Result r = ere.getResult(); errPrintln(ERR_TOOL_RESULT_CODE.get(r.getResultCode().intValue(), r.getResultCode() .toString())); if (r.getDiagnosticMessage() != null && r.getDiagnosticMessage().length() > 0) { errPrintln(LocalizableMessage.raw(r.getDiagnosticMessage())); } if (r.getMatchedDN() != null && r.getMatchedDN().length() > 0) { errPrintln(ERR_TOOL_MATCHED_DN.get(r.getMatchedDN())); } return r.getResultCode().intValue(); } catch (final LdapException e) { return printErrorMessage(this, e, ERR_LDAP_COMPARE_FAILED); } } return ResultCode.SUCCESS.intValue(); } int run(final String[] args) { int run(final String[] args) throws LDAPToolException { // Create the command-line argument parser for use with this program. final LocalizableMessage toolDescription = INFO_LDAPCOMPARE_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser( LDAPCompare.class.getName(), toolDescription, false, true, 1, 0, "attribute:value [DN ...]"); final LDAPToolArgumentParser argParser = LDAPToolArgumentParser.builder(LDAPCompare.class.getName()) .toolDescription(toolDescription) .trailingArguments(1, "attribute:value [DN ...]") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_LDAPCOMPARE.get()); ConnectionFactoryProvider connectionFactoryProvider; ConnectionFactory connectionFactory; BindRequest bindRequest; BooleanArgument continueOnError; BooleanArgument noop; BooleanArgument dryRun; BooleanArgument showUsage; IntegerArgument version; IntegerArgument ldapProtocolVersion; StringArgument assertionFilter; StringArgument controlStr; StringArgument encodingStr; @@ -177,8 +173,8 @@ controlStr = controlArgument(); argParser.addArgument(controlStr); version = ldapVersionArgument(); argParser.addArgument(version); ldapProtocolVersion = ldapVersionArgument(); argParser.addArgument(ldapProtocolVersion); encodingStr = encodingArgument(); argParser.addArgument(encodingStr); @@ -186,8 +182,8 @@ continueOnError = continueOnErrorArgument(); argParser.addArgument(continueOnError); noop = noOpArgument(); argParser.addArgument(noop); dryRun = noOpArgument(); argParser.addArgument(dryRun); verbose = verboseArgument(); argParser.addArgument(verbose); @@ -196,41 +192,17 @@ argParser.addArgument(showUsage); argParser.setUsageArgument(showUsage, getOutputStream()); } catch (final ArgumentException ae) { errPrintln(ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(ae, ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage())); } // Parse the command-line arguments provided to this program. try { argParser.parseArguments(args); // If we should just display usage or version information, then print it and exit. argParser.parseArguments(args, getErrStream(), connectionFactoryProvider); if (argParser.usageOrVersionDisplayed()) { return 0; return ResultCode.SUCCESS.intValue(); } ensureLdapProtocolVersionIsSupported(ldapProtocolVersion); connectionFactory = connectionFactoryProvider.getUnauthenticatedConnectionFactory(); bindRequest = connectionFactoryProvider.getBindRequest(); } catch (final ArgumentException ae) { argParser.displayMessageAndUsageReference(getErrStream(), ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } try { final int versionNumber = version.getIntValue(); if (versionNumber != 2 && versionNumber != 3) { argParser.displayMessageAndUsageReference( getErrStream(), ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(versionNumber))); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } catch (final ArgumentException ae) { argParser.displayMessageAndUsageReference( getErrStream(), ERR_DESCRIPTION_INVALID_VERSION.get(version.getValue())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } final ArrayList<String> dnStrings = new ArrayList<>(); final ArrayList<String> attrAndDNStrings = argParser.getTrailingArguments(); final List<String> dnStrings = new ArrayList<>(); final List<String> attrAndDNStrings = argParser.getTrailingArguments(); if (attrAndDNStrings.isEmpty()) { argParser.displayMessageAndUsageReference(getErrStream(), ERR_LDAPCOMPARE_NO_ATTR.get()); @@ -272,17 +244,15 @@ try { attributeVal = ByteString.valueOfBase64(base64); } catch (final LocalizedIllegalArgumentException e) { errPrintln(INFO_COMPARE_CANNOT_BASE64_DECODE_ASSERTION_VALUE.get()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(e, INFO_COMPARE_CANNOT_BASE64_DECODE_ASSERTION_VALUE.get()); } } else if (nextChar == '<') { try { final String filePath = remainder.substring(1, remainder.length()); attributeVal = ByteString.wrap(readBytesFromFile(filePath)); } catch (final Exception e) { errPrintln(INFO_COMPARE_CANNOT_READ_ASSERTION_VALUE_FROM_FILE.get(String .valueOf(e))); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException( e, INFO_COMPARE_CANNOT_READ_ASSERTION_VALUE_FROM_FILE.get(String.valueOf(e))); } } else { attributeVal = ByteString.valueOfUtf8(remainder); @@ -292,39 +262,14 @@ } final CompareRequest compare = Requests.newCompareRequest("", attributeType, attributeVal); if (controlStr.isPresent()) { for (final String ctrlString : controlStr.getValues()) { try { final Control ctrl = Utils.getControl(ctrlString); compare.addControl(ctrl); } catch (final DecodeException de) { errPrintln(ERR_TOOL_INVALID_CONTROL_STRING.get(ctrlString)); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } } addControlsToRequest(compare, readControls(controlStr)); if (proxyAuthzID.isPresent()) { final Control proxyControl = ProxiedAuthV2RequestControl.newControl(proxyAuthzID.getValue()); compare.addControl(proxyControl); compare.addControl(ProxiedAuthV2RequestControl.newControl(proxyAuthzID.getValue())); } if (assertionFilter.isPresent()) { final String filterString = assertionFilter.getValue(); Filter filter; try { filter = Filter.valueOf(filterString); // FIXME -- Change this to the correct OID when the official one // is assigned. final Control assertionControl = AssertionRequestControl.newControl(true, filter); compare.addControl(assertionControl); } catch (final LocalizedIllegalArgumentException le) { errPrintln(ERR_LDAP_ASSERTION_INVALID_FILTER.get(le.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } compare.addControl(readAssertionControl(assertionFilter.getValue())); } BufferedReader rdr = null; @@ -335,24 +280,15 @@ try { rdr = new BufferedReader(new FileReader(filename.getValue())); } catch (final FileNotFoundException t) { errPrintln(ERR_LDAPCOMPARE_ERROR_READING_FILE.get(filename.getValue(), t.toString())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException( t, ERR_LDAPCOMPARE_ERROR_READING_FILE.get(filename.getValue(), t.toString())); } } Connection connection = null; try { if (!noop.isPresent()) { try { connection = connectionFactory.getConnection(); if (bindRequest != null) { printPasswordPolicyResults(this, connection.bind(bindRequest)); } } catch (final LdapException ere) { return printErrorMessage(this, ere); } } try (final Connection connection = getConnection(argParser.getConnectionFactory(), argParser.getBindRequest(), dryRun, this)) { int result; if (rdr == null) { for (final String dn : dnStrings) { @@ -373,15 +309,14 @@ } } } catch (final IOException ioe) { errPrintln(ERR_LDAPCOMPARE_ERROR_READING_FILE.get(filename.getValue(), ioe .toString())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException( ioe, ERR_LDAPCOMPARE_ERROR_READING_FILE.get(filename.getValue(), ioe.toString())); } } } finally { closeSilently(connection, rdr); closeSilently(rdr); } return 0; return ResultCode.SUCCESS.intValue(); } } opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPModify.java
@@ -18,10 +18,15 @@ import static com.forgerock.opendj.cli.ArgumentConstants.*; import static com.forgerock.opendj.cli.ToolVersionHandler.newSdkVersionHandler; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolParamException; import static com.forgerock.opendj.ldap.tools.ToolsMessages.*; import static com.forgerock.opendj.cli.Utils.filterExitCode; import static com.forgerock.opendj.ldap.tools.Utils.getConnection; import static com.forgerock.opendj.ldap.tools.Utils.printlnTextMsg; import static com.forgerock.opendj.ldap.tools.Utils.readAssertionControl; import static com.forgerock.opendj.ldap.tools.Utils.readControls; import static com.forgerock.opendj.ldap.tools.Utils.ensureLdapProtocolVersionIsSupported; import static com.forgerock.opendj.ldap.tools.Utils.printErrorMessage; import static com.forgerock.opendj.ldap.tools.Utils.printPasswordPolicyResults; import static com.forgerock.opendj.cli.CommonArguments.*; import static org.forgerock.util.Utils.closeSilently; @@ -34,15 +39,11 @@ import java.util.StringTokenizer; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizedIllegalArgumentException; import org.forgerock.opendj.ldap.Connection; import org.forgerock.opendj.ldap.ConnectionFactory; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.DecodeOptions; import org.forgerock.opendj.ldap.Filter; import org.forgerock.opendj.ldap.LdapException; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.controls.AssertionRequestControl; import org.forgerock.opendj.ldap.controls.Control; import org.forgerock.opendj.ldap.controls.PostReadRequestControl; import org.forgerock.opendj.ldap.controls.PostReadResponseControl; @@ -50,7 +51,6 @@ import org.forgerock.opendj.ldap.controls.PreReadResponseControl; import org.forgerock.opendj.ldap.controls.ProxiedAuthV2RequestControl; import org.forgerock.opendj.ldap.requests.AddRequest; import org.forgerock.opendj.ldap.requests.BindRequest; import org.forgerock.opendj.ldap.requests.DeleteRequest; import org.forgerock.opendj.ldap.requests.ModifyDNRequest; import org.forgerock.opendj.ldap.requests.ModifyRequest; @@ -63,7 +63,6 @@ import org.forgerock.opendj.ldif.LDIFEntryWriter; import com.forgerock.opendj.cli.ArgumentException; import com.forgerock.opendj.cli.ArgumentParser; import com.forgerock.opendj.cli.BooleanArgument; import com.forgerock.opendj.cli.ConnectionFactoryProvider; import com.forgerock.opendj.cli.ConsoleApplication; @@ -75,7 +74,13 @@ * to the Directory Server. */ public final class LDAPModify extends ConsoleApplication { private class VisitorImpl implements ChangeRecordVisitor<Integer, java.lang.Void> { private final class VisitorImpl implements ChangeRecordVisitor<Integer, Void> { private final Connection connection; private VisitorImpl(final Connection connection) { this.connection = connection; } @Override public Integer visitChangeRecord(final Void aVoid, final AddRequest change) { for (final Control control : controls) { @@ -83,17 +88,18 @@ } final String opType = "ADD"; println(INFO_PROCESSING_OPERATION.get(opType, change.getName().toString())); if (connection != null) { if (dryRun()) { return ResultCode.SUCCESS.intValue(); } try { Result r = connection.add(change); printResult(opType, change.getName().toString(), r); return r.getResultCode().intValue(); } catch (final LdapException ere) { return printErrorMessage(LDAPModify.this, ere); return printErrorMessage(LDAPModify.this, ere, ERR_LDAP_MODIFY_FAILED); } } return ResultCode.SUCCESS.intValue(); } @Override public Integer visitChangeRecord(final Void aVoid, final DeleteRequest change) { @@ -102,17 +108,18 @@ } final String opType = "DELETE"; println(INFO_PROCESSING_OPERATION.get(opType, change.getName().toString())); if (connection != null) { if (dryRun()) { return ResultCode.SUCCESS.intValue(); } try { Result r = connection.delete(change); printResult(opType, change.getName().toString(), r); return r.getResultCode().intValue(); } catch (final LdapException ere) { return printErrorMessage(LDAPModify.this, ere); return printErrorMessage(LDAPModify.this, ere, ERR_LDAP_MODIFY_FAILED); } } return ResultCode.SUCCESS.intValue(); } @Override public Integer visitChangeRecord(final Void aVoid, final ModifyDNRequest change) { @@ -121,17 +128,18 @@ } final String opType = "MODIFY DN"; println(INFO_PROCESSING_OPERATION.get(opType, change.getName().toString())); if (connection != null) { if (dryRun()) { return ResultCode.SUCCESS.intValue(); } try { Result r = connection.modifyDN(change); printResult(opType, change.getName().toString(), r); return r.getResultCode().intValue(); } catch (final LdapException ere) { return printErrorMessage(LDAPModify.this, ere); return printErrorMessage(LDAPModify.this, ere, ERR_LDAP_MODIFY_FAILED); } } return ResultCode.SUCCESS.intValue(); } @Override public Integer visitChangeRecord(final Void aVoid, final ModifyRequest change) { @@ -140,36 +148,29 @@ } final String opType = "MODIFY"; println(INFO_PROCESSING_OPERATION.get(opType, change.getName().toString())); if (connection != null) { if (dryRun()) { return ResultCode.SUCCESS.intValue(); } try { Result r = connection.modify(change); printResult(opType, change.getName().toString(), r); return r.getResultCode().intValue(); } catch (final LdapException ere) { return printErrorMessage(LDAPModify.this, ere); return printErrorMessage(LDAPModify.this, ere, ERR_LDAP_MODIFY_FAILED); } } return ResultCode.SUCCESS.intValue(); } private void printResult(final String operationType, final String name, final Result r) { if (r.getResultCode() != ResultCode.SUCCESS && r.getResultCode() != ResultCode.REFERRAL) { final LocalizableMessage msg = INFO_OPERATION_FAILED.get(operationType); errPrintln(msg); errPrintln(ERR_TOOL_RESULT_CODE.get(r.getResultCode().intValue(), r.getResultCode())); if (r.getDiagnosticMessage() != null && r.getDiagnosticMessage().length() > 0) { errPrintln(LocalizableMessage.raw(r.getDiagnosticMessage())); } if (r.getMatchedDN() != null && r.getMatchedDN().length() > 0) { errPrintln(ERR_TOOL_MATCHED_DN.get(r.getMatchedDN())); } final ResultCode rc = r.getResultCode(); if (ResultCode.SUCCESS != rc && ResultCode.REFERRAL != rc) { printErrorMessage(LDAPModify.this, r, ERR_LDAP_MODIFY_FAILED); } else { println(INFO_OPERATION_SUCCESSFUL.get(operationType, name)); if (r.getDiagnosticMessage() != null && r.getDiagnosticMessage().length() > 0) { errPrintln(LocalizableMessage.raw(r.getDiagnosticMessage())); } if (r.getReferralURIs() != null) { for (final String uri : r.getReferralURIs()) { printlnTextMsg(LDAPModify.this, r.getDiagnosticMessage()); final List<String> referralURIs = r.getReferralURIs(); if (referralURIs != null) { for (final String uri : referralURIs) { println(LocalizableMessage.raw(uri)); } } @@ -200,9 +201,12 @@ } catch (final IOException ioe) { throw new RuntimeException(ioe); } // TODO: CSN control } private boolean dryRun() { return connection == null; } // TODO: CSN control } /** @@ -212,16 +216,19 @@ * The command-line arguments provided to this program. */ public static void main(final String[] args) { final int retCode = new LDAPModify().run(args); final LDAPModify ldapModify = new LDAPModify(); int retCode; try { retCode = ldapModify.run(args); } catch (final LDAPToolException e) { e.printErrorMessage(ldapModify); retCode = e.getResultCode(); } System.exit(filterExitCode(retCode)); } private Connection connection; private EntryWriter writer; private Collection<Control> controls; private BooleanArgument verbose; private LDAPModify() { @@ -238,22 +245,21 @@ return verbose.isPresent(); } int run(final String[] args) { int run(final String[] args) throws LDAPToolException { // Create the command-line argument parser for use with this program. final LocalizableMessage toolDescription = INFO_LDAPMODIFY_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser(LDAPModify.class.getName(), toolDescription, false); final LDAPToolArgumentParser argParser = LDAPToolArgumentParser.builder(LDAPModify.class.getName()) .toolDescription(toolDescription) .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_LDAPMODIFY.get()); ConnectionFactoryProvider connectionFactoryProvider; ConnectionFactory connectionFactory; BindRequest bindRequest; BooleanArgument continueOnError; BooleanArgument noop; BooleanArgument showUsage; IntegerArgument version; IntegerArgument ldapProtocolVersion; StringArgument assertionFilter; StringArgument controlStr; StringArgument filename; @@ -274,12 +280,9 @@ argParser.addArgument(noPropertiesFileArgument); argParser.setNoPropertiesFileArgument(noPropertiesFileArgument); filename = StringArgument.builder(OPTION_LONG_FILENAME) .shortIdentifier(OPTION_SHORT_FILENAME) .description(INFO_LDAPMODIFY_DESCRIPTION_FILENAME.get()) .valuePlaceholder(INFO_FILE_PLACEHOLDER.get()) .buildAndAddToParser(argParser); filename = filenameArgument(INFO_LDAPMODIFY_DESCRIPTION_FILENAME.get()); argParser.addArgument(filename); proxyAuthzID = StringArgument.builder(OPTION_LONG_PROXYAUTHID) .shortIdentifier(OPTION_SHORT_PROXYAUTHID) @@ -301,16 +304,12 @@ .description(INFO_DESCRIPTION_POSTREAD_ATTRS.get()) .valuePlaceholder(INFO_ATTRIBUTE_LIST_PLACEHOLDER.get()) .buildAndAddToParser(argParser); controlStr = StringArgument.builder("control") .shortIdentifier('J') .description(INFO_DESCRIPTION_CONTROLS.get()) .multiValued() .valuePlaceholder(INFO_LDAP_CONTROL_PLACEHOLDER.get()) .buildAndAddToParser(argParser); version = ldapVersionArgument(); argParser.addArgument(version); controlStr = controlArgument(); argParser.addArgument(controlStr); ldapProtocolVersion = ldapVersionArgument(); argParser.addArgument(ldapProtocolVersion); continueOnError = continueOnErrorArgument(); argParser.addArgument(continueOnError); @@ -329,119 +328,42 @@ return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } // Parse the command-line arguments provided to this program. try { argParser.parseArguments(args); // If we should just display usage or version information, then print it and exit. argParser.parseArguments(args, getErrStream(), connectionFactoryProvider); if (argParser.usageOrVersionDisplayed()) { return 0; return ResultCode.SUCCESS.intValue(); } ensureLdapProtocolVersionIsSupported(ldapProtocolVersion); connectionFactory = connectionFactoryProvider.getUnauthenticatedConnectionFactory(); bindRequest = connectionFactoryProvider.getBindRequest(); } catch (final ArgumentException ae) { argParser.displayMessageAndUsageReference(getErrStream(), ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } try { final int versionNumber = version.getIntValue(); if (versionNumber != 2 && versionNumber != 3) { errPrintln(ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(versionNumber))); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } catch (final ArgumentException ae) { errPrintln(ERR_DESCRIPTION_INVALID_VERSION.get(version.getValue())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } controls = new LinkedList<>(); if (controlStr.isPresent()) { for (final String ctrlString : controlStr.getValues()) { try { final Control ctrl = Utils.getControl(ctrlString); controls.add(ctrl); } catch (final DecodeException de) { errPrintln(ERR_TOOL_INVALID_CONTROL_STRING.get(ctrlString)); ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } } controls = readControls(controlStr); if (proxyAuthzID.isPresent()) { final Control proxyControl = ProxiedAuthV2RequestControl.newControl(proxyAuthzID.getValue()); controls.add(proxyControl); controls.add(ProxiedAuthV2RequestControl.newControl(proxyAuthzID.getValue())); } if (assertionFilter.isPresent()) { final String filterString = assertionFilter.getValue(); Filter filter; try { filter = Filter.valueOf(filterString); // FIXME -- Change this to the correct OID when the official one // is assigned. final Control assertionControl = AssertionRequestControl.newControl(true, filter); controls.add(assertionControl); } catch (final LocalizedIllegalArgumentException le) { errPrintln(ERR_LDAP_ASSERTION_INVALID_FILTER.get(le.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); controls.add(readAssertionControl(assertionFilter.getValue())); } } if (preReadAttributes.isPresent()) { final String valueStr = preReadAttributes.getValue(); final StringTokenizer tokenizer = new StringTokenizer(valueStr, ", "); final List<String> attributes = new LinkedList<>(); while (tokenizer.hasMoreTokens()) { attributes.add(tokenizer.nextToken()); } controls.add(PreReadRequestControl.newControl(true, attributes)); } if (postReadAttributes.isPresent()) { final String valueStr = postReadAttributes.getValue(); final StringTokenizer tokenizer = new StringTokenizer(valueStr, ", "); final List<String> attributes = new LinkedList<>(); while (tokenizer.hasMoreTokens()) { attributes.add(tokenizer.nextToken()); } final PostReadRequestControl control = PostReadRequestControl.newControl(true, attributes); controls.add(control); } addReadAttributesToControl(controls, preReadAttributes, true); addReadAttributesToControl(controls, postReadAttributes, false); writer = new LDIFEntryWriter(getOutputStream()); final VisitorImpl visitor = new VisitorImpl(); ChangeRecordReader reader = null; try { if (!noop.isPresent()) { try { connection = connectionFactory.getConnection(); if (bindRequest != null) { printPasswordPolicyResults(this, connection.bind(bindRequest)); } } catch (final LdapException ere) { return printErrorMessage(this, ere); } } try (final Connection connection = getConnection(argParser.getConnectionFactory(), argParser.getBindRequest(), noop, this)) { if (filename.isPresent()) { final String filePath = filename.getValue(); try { reader = new LDIFChangeRecordReader(new FileInputStream(filename.getValue())); reader = new LDIFChangeRecordReader(new FileInputStream(filePath)); } catch (final Exception e) { final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ.get(filename.getValue(), e .getLocalizedMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException( e, ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ.get(filePath, e.getLocalizedMessage())); } } else { reader = new LDIFChangeRecordReader(getInputStream()); } final VisitorImpl visitor = new VisitorImpl(connection); try { while (reader.hasNext()) { final ChangeRecord cr = reader.readChangeRecord(); @@ -451,13 +373,26 @@ } } } catch (final IOException ioe) { errPrintln(ERR_LDIF_FILE_READ_ERROR.get(filename.getValue(), ioe.getLocalizedMessage())); return ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue(); throw newToolParamException( ioe, ERR_LDIF_FILE_READ_ERROR.get(filename.getValue(), ioe.getLocalizedMessage())); } } finally { closeSilently(reader, connection); closeSilently(reader); } return ResultCode.SUCCESS.intValue(); } private void addReadAttributesToControl( final Collection<Control> controls, final StringArgument attributesArg, final boolean preRead) { if (attributesArg.isPresent()) { final StringTokenizer tokenizer = new StringTokenizer(attributesArg.getValue(), ", "); final List<String> attributes = new LinkedList<>(); while (tokenizer.hasMoreTokens()) { attributes.add(tokenizer.nextToken()); } controls.add(preRead ? PreReadRequestControl.newControl(true, attributes) : PostReadRequestControl.newControl(true, attributes)); } } } opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPPasswordModify.java
@@ -18,24 +18,26 @@ import static com.forgerock.opendj.cli.CliMessages.INFO_FILE_PLACEHOLDER; import static com.forgerock.opendj.cli.ToolVersionHandler.newSdkVersionHandler; import static com.forgerock.opendj.cli.Utils.throwIfArgumentsConflict; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolParamException; import static com.forgerock.opendj.ldap.tools.ToolsMessages.*; import static com.forgerock.opendj.cli.Utils.filterExitCode; import static com.forgerock.opendj.cli.CommonArguments.*; import static com.forgerock.opendj.ldap.tools.Utils.addControlsToRequest; import static com.forgerock.opendj.ldap.tools.Utils.ensureLdapProtocolVersionIsSupported; import static com.forgerock.opendj.ldap.tools.Utils.printErrorMessage; import static com.forgerock.opendj.ldap.tools.Utils.readControls; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.Connection; import org.forgerock.opendj.ldap.ConnectionFactory; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.LdapException; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.controls.Control; import org.forgerock.opendj.ldap.requests.PasswordModifyExtendedRequest; import org.forgerock.opendj.ldap.requests.Requests; import org.forgerock.opendj.ldap.responses.PasswordModifyExtendedResult; import com.forgerock.opendj.cli.ArgumentException; import com.forgerock.opendj.cli.ArgumentParser; import com.forgerock.opendj.cli.BooleanArgument; import com.forgerock.opendj.cli.ConnectionFactoryProvider; import com.forgerock.opendj.cli.ConsoleApplication; @@ -65,7 +67,14 @@ * The command-line arguments provided to this program. */ public static void main(final String[] args) { final int retCode = new LDAPPasswordModify().run(args); final LDAPPasswordModify ldapPasswordModify = new LDAPPasswordModify(); int retCode; try { retCode = ldapPasswordModify.run(args); } catch (final LDAPToolException e) { e.printErrorMessage(ldapPasswordModify); retCode = e.getResultCode(); } System.exit(filterExitCode(retCode)); } @@ -85,21 +94,22 @@ return verbose.isPresent(); } private int run(final String[] args) { private int run(final String[] args) throws LDAPToolException { // Create the command-line argument parser for use with this program. final LocalizableMessage toolDescription = INFO_LDAPPWMOD_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser(LDAPPasswordModify.class.getName(), toolDescription, false); final LDAPToolArgumentParser argParser = LDAPToolArgumentParser.builder(LDAPPasswordModify.class.getName()) .toolDescription(toolDescription) .needAuthenticatedConnectionFactory() .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_LDAPPASSWORDMODIFY.get()); ConnectionFactoryProvider connectionFactoryProvider; ConnectionFactory connectionFactory; FileBasedArgument currentPWFile; FileBasedArgument newPWFile; BooleanArgument showUsage; IntegerArgument version; IntegerArgument ldapProtocolVersion; StringArgument currentPW; StringArgument controlStr; StringArgument newPW; @@ -148,16 +158,11 @@ .description(INFO_LDAPPWMOD_DESCRIPTION_AUTHZID.get()) .valuePlaceholder(INFO_PROXYAUTHID_PLACEHOLDER.get()) .buildAndAddToParser(argParser); controlStr = StringArgument.builder("control") .shortIdentifier('J') .description(INFO_DESCRIPTION_CONTROLS.get()) .multiValued() .valuePlaceholder(INFO_LDAP_CONTROL_PLACEHOLDER.get()) .buildAndAddToParser(argParser); controlStr = controlArgument(); argParser.addArgument(controlStr); version = ldapVersionArgument(); argParser.addArgument(version); ldapProtocolVersion = ldapVersionArgument(); argParser.addArgument(ldapProtocolVersion); verbose = verboseArgument(); argParser.addArgument(verbose); @@ -170,66 +175,27 @@ return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } // Parse the command-line arguments provided to this program. try { argParser.parseArguments(args); // If we should just display usage or version information, then print it and exit. argParser.parseArgumentsNoBindRequest(args, getErrStream(), connectionFactoryProvider); if (argParser.usageOrVersionDisplayed()) { return 0; return ResultCode.SUCCESS.intValue(); } connectionFactory = connectionFactoryProvider.getAuthenticatedConnectionFactory(); } catch (final ArgumentException ae) { argParser.displayMessageAndUsageReference(getErrStream(), ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } ensureLdapProtocolVersionIsSupported(ldapProtocolVersion); final PasswordModifyExtendedRequest request = Requests.newPasswordModifyExtendedRequest(); addControlsToRequest(request, readControls(controlStr)); try { final int versionNumber = version.getIntValue(); if (versionNumber != 2 && versionNumber != 3) { errPrintln(ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(versionNumber))); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } catch (final ArgumentException ae) { errPrintln(ERR_DESCRIPTION_INVALID_VERSION.get(version.getValue())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } if (controlStr.isPresent()) { for (final String ctrlString : controlStr.getValues()) { try { final Control ctrl = Utils.getControl(ctrlString); request.addControl(ctrl); } catch (final DecodeException de) { errPrintln(ERR_TOOL_INVALID_CONTROL_STRING.get(ctrlString)); ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } } if (newPW.isPresent() && newPWFile.isPresent()) { final LocalizableMessage message = ERR_LDAPPWMOD_CONFLICTING_ARGS.get(newPW.getLongIdentifier(), newPWFile .getLongIdentifier()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } if (currentPW.isPresent() && currentPWFile.isPresent()) { final LocalizableMessage message = ERR_LDAPPWMOD_CONFLICTING_ARGS.get(currentPW.getLongIdentifier(), currentPWFile .getLongIdentifier()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throwIfArgumentsConflict(newPW, newPWFile); throwIfArgumentsConflict(currentPW, currentPWFile); } catch (final ArgumentException e) { throw newToolParamException(e, e.getMessageObject()); } Connection connection; try { connection = connectionFactory.getConnection(); connection = argParser.getConnectionFactory().getConnection(); } catch (final LdapException ere) { return Utils.printErrorMessage(this, ere); return printErrorMessage(this, ere, ERR_LDAPPWMOD_FAILED); } if (proxyAuthzID.isPresent()) { @@ -252,37 +218,16 @@ try { result = connection.extendedRequest(request); } catch (final LdapException e) { LocalizableMessage message = ERR_LDAPPWMOD_FAILED.get(e.getResult().getResultCode().intValue(), e .getResult().getResultCode().toString()); errPrintln(message); final String errorMessage = e.getResult().getDiagnosticMessage(); if (errorMessage != null && errorMessage.length() > 0) { message = ERR_LDAPPWMOD_FAILURE_ERROR_MESSAGE.get(errorMessage); errPrintln(message); } final String matchedDN = e.getResult().getMatchedDN(); if (matchedDN != null && matchedDN.length() > 0) { message = ERR_LDAPPWMOD_FAILURE_MATCHED_DN.get(matchedDN); errPrintln(message); } return e.getResult().getResultCode().intValue(); return printErrorMessage(this, e, ERR_LDAPPWMOD_FAILED); } println(INFO_LDAPPWMOD_SUCCESSFUL.get()); final String additionalInfo = result.getDiagnosticMessage(); if (additionalInfo != null && additionalInfo.length() > 0) { println(INFO_LDAPPWMOD_ADDITIONAL_INFO.get(additionalInfo)); } Utils.printlnTextMsg(this, INFO_LDAPPWMOD_ADDITIONAL_INFO, result.getDiagnosticMessage()); if (result.getGeneratedPassword() != null) { println(INFO_LDAPPWMOD_GENERATED_PASSWORD.get(ByteString.valueOfBytes( result.getGeneratedPassword()).toString())); println(INFO_LDAPPWMOD_GENERATED_PASSWORD.get( ByteString.valueOfBytes(result.getGeneratedPassword()).toString())); } return 0; return ResultCode.SUCCESS.intValue(); } } opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPSearch.java
@@ -16,8 +16,6 @@ */ package com.forgerock.opendj.ldap.tools; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; @@ -27,10 +25,10 @@ import java.util.StringTokenizer; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageDescriptor; import org.forgerock.i18n.LocalizedIllegalArgumentException; import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.Connection; import org.forgerock.opendj.ldap.ConnectionFactory; import org.forgerock.opendj.ldap.DN; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.DecodeOptions; @@ -40,7 +38,6 @@ import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.SearchResultHandler; import org.forgerock.opendj.ldap.SearchScope; import org.forgerock.opendj.ldap.controls.AssertionRequestControl; import org.forgerock.opendj.ldap.controls.Control; import org.forgerock.opendj.ldap.controls.EntryChangeNotificationResponseControl; import org.forgerock.opendj.ldap.controls.GetEffectiveRightsRequestControl; @@ -63,7 +60,6 @@ import org.forgerock.opendj.ldif.LDIFEntryWriter; import com.forgerock.opendj.cli.ArgumentException; import com.forgerock.opendj.cli.ArgumentParser; import com.forgerock.opendj.cli.BooleanArgument; import com.forgerock.opendj.cli.ConnectionFactoryProvider; import com.forgerock.opendj.cli.ConsoleApplication; @@ -75,8 +71,16 @@ import static com.forgerock.opendj.cli.CliMessages.INFO_NUM_ENTRIES_PLACEHOLDER; import static com.forgerock.opendj.cli.ToolVersionHandler.newSdkVersionHandler; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolParamException; import static com.forgerock.opendj.ldap.tools.Utils.addControlsToRequest; import static com.forgerock.opendj.ldap.tools.Utils.ensureLdapProtocolVersionIsSupported; import static com.forgerock.opendj.ldap.tools.Utils.printErrorMessage; import static com.forgerock.opendj.ldap.tools.Utils.printPasswordPolicyResults; import static com.forgerock.opendj.ldap.tools.Utils.printlnTextMsg; import static com.forgerock.opendj.ldap.tools.Utils.readAssertionControl; import static com.forgerock.opendj.ldap.tools.Utils.readControls; import static com.forgerock.opendj.ldap.tools.Utils.readFiltersFromFile; import static com.forgerock.opendj.ldap.tools.Utils.readFilterFromString; import static org.forgerock.util.Utils.*; import static com.forgerock.opendj.cli.ArgumentConstants.*; @@ -95,11 +99,9 @@ try { final EntryChangeNotificationResponseControl control = entry.getControl(EntryChangeNotificationResponseControl.DECODER, new DecodeOptions()); entry.getControl(EntryChangeNotificationResponseControl.DECODER, new DecodeOptions()); if (control != null) { println(INFO_LDAPSEARCH_PSEARCH_CHANGE_TYPE.get(control.getChangeType() .toString())); println(INFO_LDAPSEARCH_PSEARCH_CHANGE_TYPE.get(control.getChangeType().toString())); final DN previousDN = control.getPreviousName(); if (previousDN != null) { println(INFO_LDAPSEARCH_PSEARCH_PREVIOUS_DN.get(previousDN.toString())); @@ -111,20 +113,14 @@ try { final AccountUsabilityResponseControl control = entry.getControl(AccountUsabilityResponseControl.DECODER, new DecodeOptions()); entry.getControl(AccountUsabilityResponseControl.DECODER, new DecodeOptions()); if (control != null) { println(INFO_LDAPSEARCH_ACCTUSABLE_HEADER.get()); if (control.isUsable()) { println(INFO_LDAPSEARCH_ACCTUSABLE_IS_USABLE.get()); if (control.getSecondsBeforeExpiration() > 0) { final int timeToExp = control.getSecondsBeforeExpiration(); final LocalizableMessage timeToExpStr = secondsToTimeString(timeToExp); println(INFO_LDAPSEARCH_ACCTUSABLE_TIME_UNTIL_EXPIRATION .get(timeToExpStr)); println(INFO_LDAPSEARCH_ACCTUSABLE_TIME_UNTIL_EXPIRATION.get( secondsToTimeString(control.getSecondsBeforeExpiration()))); } } else { println(INFO_LDAPSEARCH_ACCTUSABLE_NOT_USABLE.get()); @@ -136,21 +132,16 @@ } if (control.isExpired()) { println(INFO_LDAPSEARCH_ACCTUSABLE_PW_EXPIRED.get()); if (control.getRemainingGraceLogins() > 0) { println(INFO_LDAPSEARCH_ACCTUSABLE_REMAINING_GRACE.get(control .getRemainingGraceLogins())); println(INFO_LDAPSEARCH_ACCTUSABLE_REMAINING_GRACE.get( control.getRemainingGraceLogins())); } } if (control.isLocked()) { println(INFO_LDAPSEARCH_ACCTUSABLE_LOCKED.get()); if (control.getSecondsBeforeUnlock() > 0) { final int timeToUnlock = control.getSecondsBeforeUnlock(); final LocalizableMessage timeToUnlockStr = secondsToTimeString(timeToUnlock); println(INFO_LDAPSEARCH_ACCTUSABLE_TIME_UNTIL_UNLOCK .get(timeToUnlockStr)); println(INFO_LDAPSEARCH_ACCTUSABLE_TIME_UNTIL_UNLOCK.get( secondsToTimeString(control.getSecondsBeforeUnlock()))); } } } @@ -184,7 +175,17 @@ */ public static void main(final String[] args) { final int retCode = new LDAPSearch().run(args); final LDAPSearch ldapSearch = new LDAPSearch(); int retCode; try { retCode = ldapSearch.run(args); } catch (final LDAPToolException e) { e.printErrorMessage(ldapSearch); retCode = e.getResultCode(); } catch (final ArgumentException e) { ldapSearch.errPrintln(ERR_ERROR_PARSING_ARGS.get(e.getMessageObject())); retCode = ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } System.exit(filterExitCode(retCode)); } @@ -217,18 +218,17 @@ } /** Run ldapsearch with provided command-line arguments. */ int run(final String[] args) { int run(final String[] args) throws LDAPToolException, ArgumentException { // Create the command-line argument parser for use with this program. final LocalizableMessage toolDescription = INFO_LDAPSEARCH_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser(LDAPSearch.class.getName(), toolDescription, false, true, 0, 0, "[filter] [attributes ...]"); final LDAPToolArgumentParser argParser = LDAPToolArgumentParser.builder(LDAPSearch.class.getName()) .toolDescription(toolDescription) .trailingArguments("[filter] [attributes ...]") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_LDAPSEARCH.get()); ConnectionFactoryProvider connectionFactoryProvider; ConnectionFactory connectionFactory; BindRequest bindRequest; BooleanArgument countEntries; BooleanArgument dontWrap; @@ -236,11 +236,11 @@ BooleanArgument typesOnly; IntegerArgument simplePageSize; IntegerArgument timeLimit; IntegerArgument version; IntegerArgument ldapProtocolVersion; StringArgument baseDN; StringArgument controlStr; MultiChoiceArgument<DereferenceAliasesPolicy> dereferencePolicy; StringArgument filename; StringArgument filterFile; StringArgument matchedValuesFilter; StringArgument pSearchInfo; MultiChoiceArgument<SearchScope> searchScope; @@ -253,8 +253,7 @@ IntegerArgument sizeLimit; try { connectionFactoryProvider = new ConnectionFactoryProvider(argParser, this); final StringArgument propertiesFileArgument = propertiesFileArgument(); final StringArgument propertiesFileArgument = propertiesFileArgument(); argParser.addArgument(propertiesFileArgument); argParser.setFilePropertiesArgument(propertiesFileArgument); @@ -273,12 +272,9 @@ searchScope = searchScopeArgument(); argParser.addArgument(searchScope); filename = StringArgument.builder(OPTION_LONG_FILENAME) .shortIdentifier(OPTION_SHORT_FILENAME) .description(INFO_SEARCH_DESCRIPTION_FILENAME.get()) .valuePlaceholder(INFO_FILE_PLACEHOLDER.get()) .buildAndAddToParser(argParser); filterFile = filenameArgument(INFO_SEARCH_DESCRIPTION_FILENAME.get()); argParser.addArgument(filterFile); proxyAuthzID = StringArgument.builder(OPTION_LONG_PROXYAUTHID) .shortIdentifier(OPTION_SHORT_PROXYAUTHID) @@ -322,14 +318,10 @@ .description(INFO_DESCRIPTION_VLV.get()) .valuePlaceholder(INFO_VLV_PLACEHOLDER.get()) .buildAndAddToParser(argParser); controlStr = StringArgument.builder("control") .shortIdentifier('J') .description(INFO_DESCRIPTION_CONTROLS.get()) .docDescriptionSupplement(SUPPLEMENT_DESCRIPTION_CONTROLS.get()) .multiValued() .valuePlaceholder(INFO_LDAP_CONTROL_PLACEHOLDER.get()) .buildAndAddToParser(argParser); controlStr = controlArgument(); argParser.addArgument(controlStr); effectiveRightsUser = StringArgument.builder(OPTION_LONG_EFFECTIVERIGHTSUSER) .shortIdentifier(OPTION_SHORT_EFFECTIVERIGHTSUSER) @@ -344,8 +336,8 @@ .valuePlaceholder(INFO_ATTRIBUTE_PLACEHOLDER.get()) .buildAndAddToParser(argParser); version = ldapVersionArgument(); argParser.addArgument(version); ldapProtocolVersion = ldapVersionArgument(); argParser.addArgument(ldapProtocolVersion); dereferencePolicy = MultiChoiceArgument.<DereferenceAliasesPolicy>builder("dereferencePolicy") @@ -397,68 +389,28 @@ argParser.addArgument(showUsage); argParser.setUsageArgument(showUsage, getOutputStream()); } catch (final ArgumentException ae) { errPrintln(ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(ae, ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage())); } // Parse the command-line arguments provided to this program. try { argParser.parseArguments(args); // If we should just display usage or version information, // then print it and exit. argParser.parseArguments(args, getErrStream(), connectionFactoryProvider); if (argParser.usageOrVersionDisplayed()) { return 0; } connectionFactory = connectionFactoryProvider.getUnauthenticatedConnectionFactory(); bindRequest = connectionFactoryProvider.getBindRequest(); } catch (final ArgumentException ae) { argParser.displayMessageAndUsageReference(getErrStream(), ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); return ResultCode.SUCCESS.intValue(); } final List<Filter> filters = new LinkedList<>(); final List<String> attributes = new LinkedList<>(); final ArrayList<String> filterAndAttributeStrings = argParser.getTrailingArguments(); final List<String> filterAndAttributeStrings = argParser.getTrailingArguments(); if (!filterAndAttributeStrings.isEmpty()) { /* The list of trailing arguments should be structured as follow: - If a filter file is present, trailing arguments are considered as attributes - If filter file is not present, the first trailing argument is considered the filter, the other as attributes.*/ if (!filename.isPresent()) { final String filterString = filterAndAttributeStrings.remove(0); try { filters.add(Filter.valueOf(filterString)); } catch (final LocalizedIllegalArgumentException e) { errPrintln(e.getMessageObject()); return ResultCode.CLIENT_SIDE_FILTER_ERROR.intValue(); // If filter file is not present, the first trailing argument is considered the filter if (!filterFile.isPresent()) { filters.add(readFilterFromString(filterAndAttributeStrings.remove(0))); } } // The rest are attributes // The rest of trailing argument are attributes attributes.addAll(filterAndAttributeStrings); } if (filename.isPresent()) { // Read the filter strings. try (BufferedReader in = new BufferedReader(new FileReader(filename.getValue()))) { String line = null; while ((line = in.readLine()) != null) { if ("".equals(line.trim())) { // ignore empty lines. continue; } filters.add(Filter.valueOf(line)); } } catch (final LocalizedIllegalArgumentException e) { errPrintln(e.getMessageObject()); return ResultCode.CLIENT_SIDE_FILTER_ERROR.intValue(); } catch (final IOException e) { errPrintln(LocalizableMessage.raw(e.toString())); return ResultCode.CLIENT_SIDE_FILTER_ERROR.intValue(); } if (filterFile.isPresent()) { filters.addAll(readFiltersFromFile(filterFile.getValue())); } if (filters.isEmpty()) { @@ -466,182 +418,43 @@ return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } SearchScope scope; final SearchScope scope = searchScope.getTypedValue(); final SearchRequest search; try { scope = searchScope.getTypedValue(); } catch (final ArgumentException ex1) { errPrintln(ex1.getMessageObject()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } SearchRequest search; try { search = Requests.newSearchRequest(DN.valueOf(baseDN.getValue()), scope, filters.get(0), search = Requests.newSearchRequest(DN.valueOf(baseDN.getValue()), scope, filters.get(0), attributes.toArray(new String[attributes.size()])); ensureLdapProtocolVersionIsSupported(ldapProtocolVersion); } catch (final LocalizedIllegalArgumentException e) { errPrintln(e.getMessageObject()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } // Read the LDAP version number. try { final int versionNumber = version.getIntValue(); if (versionNumber != 2 && versionNumber != 3) { errPrintln(ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(versionNumber))); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } catch (final ArgumentException ae) { errPrintln(ERR_DESCRIPTION_INVALID_VERSION.get(version.getValue())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } search.setTypesOnly(typesOnly.isPresent()); // searchOptions.setShowOperations(noop.isPresent()); // searchOptions.setVerbose(verbose.isPresent()); // searchOptions.setContinueOnError(continueOnError.isPresent()); // searchOptions.setEncoding(encodingStr.getValue()); // searchOptions.setCountMatchingEntries(countEntries.isPresent()); try { search.setTimeLimit(timeLimit.getIntValue()); search.setSizeLimit(sizeLimit.getIntValue()); } catch (final ArgumentException ex1) { errPrintln(ex1.getMessageObject()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } try { search.setDereferenceAliasesPolicy(dereferencePolicy.getTypedValue()); } catch (final ArgumentException ex1) { errPrintln(ex1.getMessageObject()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } if (controlStr.isPresent()) { for (final String ctrlString : controlStr.getValues()) { try { final Control ctrl = Utils.getControl(ctrlString); search.addControl(ctrl); } catch (final DecodeException de) { errPrintln(ERR_TOOL_INVALID_CONTROL_STRING.get(ctrlString)); ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } } addControlsToRequest(search, readControls(controlStr)); if (effectiveRightsUser.isPresent()) { final String authzID = effectiveRightsUser.getValue(); if (!authzID.startsWith("dn:")) { errPrintln(ERR_EFFECTIVERIGHTS_INVALID_AUTHZID.get(authzID)); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(ERR_EFFECTIVERIGHTS_INVALID_AUTHZID.get(authzID)); } final Control effectiveRightsControl = GetEffectiveRightsRequestControl.newControl(false, authzID.substring(3), effectiveRightsAttrs.getValues().toArray( new String[effectiveRightsAttrs.getValues().size()])); search.addControl(effectiveRightsControl); final List<String> attrValues = effectiveRightsAttrs.getValues(); search.addControl(GetEffectiveRightsRequestControl.newControl( false, authzID.substring(3), attrValues.toArray(new String[attrValues.size()]))); } if (proxyAuthzID.isPresent()) { final Control proxyControl = ProxiedAuthV2RequestControl.newControl(proxyAuthzID.getValue()); search.addControl(proxyControl); search.addControl(ProxiedAuthV2RequestControl.newControl(proxyAuthzID.getValue())); } if (pSearchInfo.isPresent()) { final String infoString = StaticUtils.toLowerCase(pSearchInfo.getValue().trim()); boolean changesOnly = true; boolean returnECs = true; final StringTokenizer tokenizer = new StringTokenizer(infoString, ":"); if (!tokenizer.hasMoreTokens()) { errPrintln(ERR_PSEARCH_MISSING_DESCRIPTOR.get()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } else { final String token = tokenizer.nextToken(); if (!"ps".equals(token)) { errPrintln(ERR_PSEARCH_DOESNT_START_WITH_PS.get(infoString)); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } final ArrayList<PersistentSearchChangeType> ct = new ArrayList<>(4); if (tokenizer.hasMoreTokens()) { final StringTokenizer st = new StringTokenizer(tokenizer.nextToken(), ", "); if (!st.hasMoreTokens()) { ct.add(PersistentSearchChangeType.ADD); ct.add(PersistentSearchChangeType.DELETE); ct.add(PersistentSearchChangeType.MODIFY); ct.add(PersistentSearchChangeType.MODIFY_DN); } else { do { final String token = st.nextToken(); if ("add".equals(token)) { ct.add(PersistentSearchChangeType.ADD); } else if ("delete".equals(token) || "del".equals(token)) { ct.add(PersistentSearchChangeType.DELETE); } else if ("modify".equals(token) || "mod".equals(token)) { ct.add(PersistentSearchChangeType.MODIFY); } else if ("modifydn".equals(token) || "moddn".equals(token) || "modrdn".equals(token)) { ct.add(PersistentSearchChangeType.MODIFY_DN); } else if ("any".equals(token) || "all".equals(token)) { ct.add(PersistentSearchChangeType.ADD); ct.add(PersistentSearchChangeType.DELETE); ct.add(PersistentSearchChangeType.MODIFY); ct.add(PersistentSearchChangeType.MODIFY_DN); } else { errPrintln(ERR_PSEARCH_INVALID_CHANGE_TYPE.get(token)); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } while (st.hasMoreTokens()); } } if (tokenizer.hasMoreTokens()) { final String token = tokenizer.nextToken(); if ("1".equals(token) || "true".equals(token) || "yes".equals(token)) { changesOnly = true; } else if ("0".equals(token) || "false".equals(token) || "no".equals(token)) { changesOnly = false; } else { errPrintln(ERR_PSEARCH_INVALID_CHANGESONLY.get(token)); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } if (tokenizer.hasMoreTokens()) { final String token = tokenizer.nextToken(); if ("1".equals(token) || "true".equals(token) || "yes".equals(token)) { returnECs = true; } else if ("0".equals(token) || "false".equals(token) || "no".equals(token)) { returnECs = false; } else { errPrintln(ERR_PSEARCH_INVALID_RETURN_ECS.get(token)); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } final PersistentSearchRequestControl psearchControl = PersistentSearchRequestControl.newControl(true, changesOnly, returnECs, ct .toArray(new PersistentSearchChangeType[ct.size()])); search.addControl(psearchControl); search.addControl(computePSearchControl(pSearchInfo)); } if (assertionFilter.isPresent()) { final String filterString = assertionFilter.getValue(); Filter filter; try { filter = Filter.valueOf(filterString); // FIXME -- Change this to the correct OID when the official one // is assigned. final Control assertionControl = AssertionRequestControl.newControl(true, filter); search.addControl(assertionControl); } catch (final LocalizedIllegalArgumentException le) { errPrintln(ERR_LDAP_ASSERTION_INVALID_FILTER.get(le.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } search.addControl(readAssertionControl(assertionFilter.getValue())); } if (matchedValuesFilter.isPresent()) { @@ -649,84 +462,33 @@ final List<Filter> mvFilters = new ArrayList<>(); for (final String s : mvFilterStrings) { try { final Filter f = Filter.valueOf(s); mvFilters.add(f); mvFilters.add(Filter.valueOf(s)); } catch (final LocalizedIllegalArgumentException le) { errPrintln(ERR_LDAP_MATCHEDVALUES_INVALID_FILTER.get(le.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(le, ERR_LDAP_MATCHEDVALUES_INVALID_FILTER.get(le.getMessage())); } } final MatchedValuesRequestControl mvc = MatchedValuesRequestControl.newControl(true, mvFilters); search.addControl(mvc); search.addControl(MatchedValuesRequestControl.newControl(true, mvFilters)); } if (sortOrder.isPresent()) { try { search.addControl(ServerSideSortRequestControl.newControl(false, sortOrder .getValue())); search.addControl(ServerSideSortRequestControl.newControl(false, sortOrder.getValue())); } catch (final LocalizedIllegalArgumentException le) { errPrintln(ERR_LDAP_SORTCONTROL_INVALID_ORDER.get(le.getMessageObject())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(le, ERR_LDAP_SORTCONTROL_INVALID_ORDER.get(le.getMessageObject())); } } if (vlvDescriptor.isPresent()) { if (!sortOrder.isPresent()) { final LocalizableMessage message = ERR_LDAPSEARCH_VLV_REQUIRES_SORT.get(vlvDescriptor.getLongIdentifier(), sortOrder.getLongIdentifier()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } final StringTokenizer tokenizer = new StringTokenizer(vlvDescriptor.getValue(), ":"); final int numTokens = tokenizer.countTokens(); if (numTokens == 3) { try { final int beforeCount = Integer.parseInt(tokenizer.nextToken()); final int afterCount = Integer.parseInt(tokenizer.nextToken()); final ByteString assertionValue = ByteString.valueOfUtf8(tokenizer.nextToken()); search.addControl(VirtualListViewRequestControl.newAssertionControl(true, assertionValue, beforeCount, afterCount, null)); } catch (final Exception e) { errPrintln(ERR_LDAPSEARCH_VLV_INVALID_DESCRIPTOR.get()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } else if (numTokens == 4) { try { final int beforeCount = Integer.parseInt(tokenizer.nextToken()); final int afterCount = Integer.parseInt(tokenizer.nextToken()); final int offset = Integer.parseInt(tokenizer.nextToken()); final int contentCount = Integer.parseInt(tokenizer.nextToken()); search.addControl(VirtualListViewRequestControl.newOffsetControl(true, offset, contentCount, beforeCount, afterCount, null)); } catch (final Exception e) { errPrintln(ERR_LDAPSEARCH_VLV_INVALID_DESCRIPTOR.get()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } else { errPrintln(ERR_LDAPSEARCH_VLV_INVALID_DESCRIPTOR.get()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } search.addControl(readVLVControl(vlvDescriptor, sortOrder)); } int pageSize = 0; if (simplePageSize.isPresent()) { if (filters.size() > 1) { errPrintln(ERR_PAGED_RESULTS_REQUIRES_SINGLE_FILTER.get()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(ERR_PAGED_RESULTS_REQUIRES_SINGLE_FILTER.get()); } try { pageSize = simplePageSize.getIntValue(); search.addControl(SimplePagedResultsControl.newControl(true, pageSize, ByteString .empty())); } catch (final ArgumentException ae) { errPrintln(ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } search.addControl(SimplePagedResultsControl.newControl(true, pageSize, ByteString.empty())); } int wrapColumn = 80; @@ -740,10 +502,11 @@ processing was successful or that there were no matching entries, based on countEntries.isPresent() (but in either case the return value should be zero).*/ return 0; return ResultCode.SUCCESS.intValue(); } try (Connection connection = connectionFactory.getConnection()) { try (Connection connection = argParser.getConnectionFactory().getConnection()) { final BindRequest bindRequest = argParser.getBindRequest(); if (bindRequest != null) { printPasswordPolicyResults(this, connection.bind(bindRequest)); } @@ -755,10 +518,8 @@ Result result = connection.search(search, resultHandler); try { final ServerSideSortResponseControl control = result.getControl(ServerSideSortResponseControl.DECODER, new DecodeOptions()); if (control != null && control.getResult() != ResultCode.SUCCESS) { result.getControl(ServerSideSortResponseControl.DECODER, new DecodeOptions()); if (control != null && ResultCode.SUCCESS != control.getResult()) { println(WARN_LDAPSEARCH_SORT_ERROR.get(control.getResult().toString())); } } catch (final DecodeException e) { @@ -767,21 +528,13 @@ try { final VirtualListViewResponseControl control = result.getControl(VirtualListViewResponseControl.DECODER, new DecodeOptions()); result.getControl(VirtualListViewResponseControl.DECODER, new DecodeOptions()); if (control != null) { if (control.getResult() == ResultCode.SUCCESS) { LocalizableMessage msg = INFO_LDAPSEARCH_VLV_TARGET_OFFSET.get(control .getTargetPosition()); println(msg); msg = INFO_LDAPSEARCH_VLV_CONTENT_COUNT.get(control.getContentCount()); println(msg); if (ResultCode.SUCCESS == control.getResult()) { println(INFO_LDAPSEARCH_VLV_TARGET_OFFSET.get(control.getTargetPosition())); println(INFO_LDAPSEARCH_VLV_CONTENT_COUNT.get(control.getContentCount())); } else { final LocalizableMessage msg = WARN_LDAPSEARCH_VLV_ERROR.get(control.getResult().toString()); println(msg); println(WARN_LDAPSEARCH_VLV_ERROR.get(control.getResult().toString())); } } } catch (final DecodeException e) { @@ -790,9 +543,8 @@ try { SimplePagedResultsControl control = result.getControl(SimplePagedResultsControl.DECODER, new DecodeOptions()); if (control != null && control.getCookie().length() > 0) { result.getControl(SimplePagedResultsControl.DECODER, new DecodeOptions()); if (control != null && !control.getCookie().isEmpty()) { if (!isQuiet()) { pressReturnToContinue(); } @@ -811,15 +563,10 @@ } errPrintln(); errPrintln(ERR_TOOL_RESULT_CODE.get(result.getResultCode().intValue(), result .getResultCode().toString())); if (result.getDiagnosticMessage() != null && result.getDiagnosticMessage().length() > 0) { errPrintln(LocalizableMessage.raw(result.getDiagnosticMessage())); } if (result.getMatchedDN() != null && result.getMatchedDN().length() > 0) { errPrintln(ERR_TOOL_MATCHED_DN.get(result.getMatchedDN())); } final ResultCode rc = result.getResultCode(); errPrintln(ERR_TOOL_RESULT_CODE.get(rc.intValue(), rc.toString())); printlnTextMsg(this, result.getDiagnosticMessage()); printlnTextMsg(this, ERR_TOOL_MATCHED_DN, result.getMatchedDN()); filterIndex++; if (filterIndex < filters.size()) { @@ -832,11 +579,133 @@ println(INFO_LDAPSEARCH_MATCHING_ENTRY_COUNT.get(resultHandler.entryCount)); println(); } return 0; return ResultCode.SUCCESS.intValue(); } catch (final LdapException ere) { return printErrorMessage(this, ere); return printErrorMessage(this, ere, ERR_LDAP_SEARCH_FAILED); } finally { closeSilently(ldifWriter); } } private Control readVLVControl(final StringArgument vlvDescriptor, final StringArgument sortOrder) throws LDAPToolException { if (!sortOrder.isPresent()) { throw newToolParamException(ERR_LDAPSEARCH_VLV_REQUIRES_SORT.get( vlvDescriptor.getLongIdentifier(), sortOrder.getLongIdentifier())); } final StringTokenizer tokenizer = new StringTokenizer(vlvDescriptor.getValue(), ":"); final int numTokens = tokenizer.countTokens(); try { if (numTokens == 3) { final int beforeCount = Integer.parseInt(tokenizer.nextToken()); final int afterCount = Integer.parseInt(tokenizer.nextToken()); final ByteString assertionValue = ByteString.valueOfUtf8(tokenizer.nextToken()); return VirtualListViewRequestControl.newAssertionControl( true, assertionValue, beforeCount, afterCount, null); } else if (numTokens == 4) { final int beforeCount = Integer.parseInt(tokenizer.nextToken()); final int afterCount = Integer.parseInt(tokenizer.nextToken()); final int offset = Integer.parseInt(tokenizer.nextToken()); final int contentCount = Integer.parseInt(tokenizer.nextToken()); return VirtualListViewRequestControl.newOffsetControl( true, offset, contentCount, beforeCount, afterCount, null); } else { throw newToolParamException(ERR_LDAPSEARCH_VLV_INVALID_DESCRIPTOR.get()); } } catch (final Exception e) { throw newToolParamException(e, ERR_LDAPSEARCH_VLV_INVALID_DESCRIPTOR.get()); } } private Control computePSearchControl(final StringArgument pSearchInfo) throws LDAPToolException { final String infoString = StaticUtils.toLowerCase(pSearchInfo.getValue().trim()); final StringTokenizer tokenizer = new StringTokenizer(infoString, ":"); if (!tokenizer.hasMoreTokens()) { throw newToolParamException(ERR_PSEARCH_MISSING_DESCRIPTOR.get()); } final String pSearchToken = tokenizer.nextToken(); if (!"ps".equals(pSearchToken)) { throw newToolParamException(ERR_PSEARCH_DOESNT_START_WITH_PS.get(infoString)); } final List<PersistentSearchChangeType> pSearchChangeTypes = new ArrayList<>(4); if (tokenizer.hasMoreTokens()) { final StringTokenizer st = new StringTokenizer(tokenizer.nextToken(), ", "); if (!st.hasMoreTokens()) { addAllPersistentSearchChangeTypes(pSearchChangeTypes); } else { do { addPersistentSearchChangeTypes(st.nextToken(), pSearchChangeTypes); } while (st.hasMoreTokens()); } } boolean changesOnly = true; if (tokenizer.hasMoreTokens()) { changesOnly = readBooleanToken(tokenizer.nextToken(), ERR_PSEARCH_INVALID_CHANGESONLY); } boolean returnECs = true; if (tokenizer.hasMoreTokens()) { returnECs = readBooleanToken(tokenizer.nextToken(), ERR_PSEARCH_INVALID_RETURN_ECS); } return PersistentSearchRequestControl.newControl(true, changesOnly, returnECs, pSearchChangeTypes.toArray(new PersistentSearchChangeType[pSearchChangeTypes.size()])); } private boolean readBooleanToken(final String token, final LocalizableMessageDescriptor.Arg1<Object> errorMsg) throws LDAPToolException { switch (token) { case "1": case "true": case "yes": return true; case "0": case "false": case "no": return false; default: throw newToolParamException(errorMsg.get(token)); } } private void addPersistentSearchChangeTypes( final String token, final List<PersistentSearchChangeType> pSearchChangeTypes) throws LDAPToolException { switch (token) { case "add": pSearchChangeTypes.add(PersistentSearchChangeType.ADD); break; case "del": case "delete": pSearchChangeTypes.add(PersistentSearchChangeType.DELETE); break; case "mod": case "modify": pSearchChangeTypes.add(PersistentSearchChangeType.MODIFY); break; case "moddn": case "modrdn": case "modifydn": pSearchChangeTypes.add(PersistentSearchChangeType.MODIFY_DN); break; case "any": case "all": addAllPersistentSearchChangeTypes(pSearchChangeTypes); break; default: throw newToolParamException(ERR_PSEARCH_INVALID_CHANGE_TYPE.get(token)); } } private void addAllPersistentSearchChangeTypes(final List<PersistentSearchChangeType> pSearchChangeTypes) { pSearchChangeTypes.add(PersistentSearchChangeType.ADD); pSearchChangeTypes.add(PersistentSearchChangeType.DELETE); pSearchChangeTypes.add(PersistentSearchChangeType.MODIFY); pSearchChangeTypes.add(PersistentSearchChangeType.MODIFY_DN); } } opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPToolArgumentParser.java
New file @@ -0,0 +1,161 @@ /* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2016 ForgeRock AS. */ package com.forgerock.opendj.ldap.tools; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolExceptionAlreadyPrinted; import static com.forgerock.opendj.ldap.tools.ToolsMessages.ERR_ERROR_PARSING_ARGS; import java.io.PrintStream; import com.forgerock.opendj.cli.ArgumentException; import com.forgerock.opendj.cli.ArgumentParser; import com.forgerock.opendj.cli.ConnectionFactoryProvider; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.opendj.ldap.ConnectionFactory; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.requests.BindRequest; /** * Facility class to help ldap* tools to parse arguments and get {@link org.forgerock.opendj.ldap.ConnectionFactory} * and {@link org.forgerock.opendj.ldap.requests.BindRequest} objects back. */ final class LDAPToolArgumentParser extends ArgumentParser { private static final boolean WITH_BIND_REQUEST = true; private static final boolean WITHOUT_BIND_REQUEST = false; /** * Returns a builder which can be used for incrementally constructing a new * {@link LDAPToolArgumentParser}. * * @param mainClassName * The tool main class name. * @return A builder to continue building the parser. */ static Builder builder(final String mainClassName) { return new Builder(mainClassName); } ConnectionFactory getConnectionFactory() { return connectionFactory; } BindRequest getBindRequest() { return bindRequest; } /** A fluent API for incrementally constructing ldap argument parser. */ static final class Builder { private final String mainClassName; private LocalizableMessage toolDescription; private boolean allowTrailingArgs; private int minTrailingArguments; private int maxTrailingArguments; private String trailingArgsDisplayName; private boolean needAuthenticatedConnectionFactory; Builder(final String mainClassName) { this.mainClassName = mainClassName; } Builder toolDescription(final LocalizableMessage toolDescription) { this.toolDescription = toolDescription; return this; } /** No trailing arguments number limitations. **/ Builder trailingArguments(final String displayNames) { return trailingArguments(0, 0, displayNames); } /** Specify that the tool accept exactly the provided number of trailing argument(s). */ Builder trailingArguments(final int nbTrailingArguments, final String displayNames) { return trailingArguments(nbTrailingArguments, nbTrailingArguments, displayNames); } /** Only specifying the minimum number of trailing arguments implies that this number has no upper bound. **/ Builder trailingArgumentsUnbounded(final int min, final String displayNames) { return trailingArguments(min, 0, displayNames); } Builder trailingArguments(final int min, final int max, final String displayNames) { this.minTrailingArguments = min; this.maxTrailingArguments = max; this.trailingArgsDisplayName = displayNames; this.allowTrailingArgs = true; return this; } Builder needAuthenticatedConnectionFactory() { this.needAuthenticatedConnectionFactory = true; return this; } LDAPToolArgumentParser build() { return new LDAPToolArgumentParser(mainClassName, toolDescription, false, allowTrailingArgs, minTrailingArguments, maxTrailingArguments, trailingArgsDisplayName, needAuthenticatedConnectionFactory); } } private ConnectionFactory connectionFactory; private BindRequest bindRequest; private final boolean needAuthenticatedCF; private LDAPToolArgumentParser(final String mainClassName, final LocalizableMessage toolDescription, final boolean longArgumentsCaseSensitive, final boolean allowsTrailingArguments, final int minTrailingArguments, final int maxTrailingArguments, final String trailingArgsDisplayName, final boolean needAuthenticatedCF) { super(mainClassName, toolDescription, longArgumentsCaseSensitive, allowsTrailingArguments, minTrailingArguments, maxTrailingArguments, trailingArgsDisplayName); this.needAuthenticatedCF = needAuthenticatedCF; } void parseArguments(final String[] args, final PrintStream stream, final ConnectionFactoryProvider provider) throws LDAPToolException { parseLdapToolArgument(args, provider, stream, WITH_BIND_REQUEST); } void parseArgumentsNoBindRequest(final String[] args, final PrintStream stream, final ConnectionFactoryProvider provider) throws LDAPToolException { parseLdapToolArgument(args, provider, stream, WITHOUT_BIND_REQUEST); } private void parseLdapToolArgument(final String[] args, final ConnectionFactoryProvider provider, final PrintStream stream, final boolean withBindRequest) throws LDAPToolException { try { parseArguments(args); if (usageOrVersionDisplayed()) { return; } connectionFactory = needAuthenticatedCF ? provider.getAuthenticatedConnectionFactory() : provider.getUnauthenticatedConnectionFactory(); if (withBindRequest) { bindRequest = provider.getBindRequest(); } } catch (final ArgumentException ae) { displayMessageAndUsageReference(stream, ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); throw newToolExceptionAlreadyPrinted(ae, ResultCode.CLIENT_SIDE_PARAM_ERROR); } } } opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDAPToolException.java
New file @@ -0,0 +1,68 @@ /* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2016 ForgeRock AS. */ package com.forgerock.opendj.ldap.tools; import com.forgerock.opendj.cli.ConsoleApplication; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.opendj.ldap.ResultCode; @SuppressWarnings("serial") final class LDAPToolException extends Exception { static LDAPToolException newToolExceptionAlreadyPrinted(final Exception rootException, ResultCode rc) { return new LDAPToolException(rootException, rc); } static LDAPToolException newToolParamException(final Exception rootException, final LocalizableMessage message) { return new LDAPToolException(rootException, ResultCode.CLIENT_SIDE_PARAM_ERROR, message); } static LDAPToolException newToolParamException(final LocalizableMessage message) { return new LDAPToolException(null, ResultCode.CLIENT_SIDE_PARAM_ERROR, message); } static LDAPToolException newToolException(final Exception rootException, final ResultCode rc, final LocalizableMessage message) { return new LDAPToolException(rootException, rc, message); } private final ResultCode resultCode; private final LocalizableMessage errorMsg; private LDAPToolException(final Exception rootException, final ResultCode rc) { super(rootException); this.resultCode = rc; this.errorMsg = null; } private LDAPToolException(final Exception rootException, final ResultCode rc, final LocalizableMessage errorMsg) { super(errorMsg.toString(), rootException); this.resultCode = rc; this.errorMsg = errorMsg; } int getResultCode() { return resultCode.intValue(); } void printErrorMessage(final ConsoleApplication console) { if (errorMsg != null) { console.errPrintln(errorMsg); } } } opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDIFDiff.java
@@ -19,15 +19,16 @@ import static com.forgerock.opendj.cli.ArgumentConstants.OPTION_LONG_OUTPUT_LDIF_FILENAME; import static com.forgerock.opendj.cli.ArgumentConstants.OPTION_SHORT_OUTPUT_LDIF_FILENAME; import static com.forgerock.opendj.cli.ToolVersionHandler.newSdkVersionHandler; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolParamException; import static com.forgerock.opendj.ldap.tools.ToolsMessages.*; import static com.forgerock.opendj.cli.Utils.filterExitCode; import static com.forgerock.opendj.cli.CommonArguments.*; import static com.forgerock.opendj.ldap.tools.Utils.getLDIFToolInputStream; import static com.forgerock.opendj.ldap.tools.Utils.getLDIFToolOutputStream; import static com.forgerock.opendj.ldap.tools.Utils.parseArguments; import static org.forgerock.util.Utils.closeSilently; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -59,7 +60,14 @@ * The command-line arguments provided to this program. */ public static void main(final String[] args) { final int retCode = new LDIFDiff().run(args); final LDIFDiff ldifDiff = new LDIFDiff(); int retCode; try { retCode = ldifDiff.run(args); } catch (final LDAPToolException e) { e.printErrorMessage(ldifDiff); retCode = e.getResultCode(); } System.exit(filterExitCode(retCode)); } @@ -67,11 +75,13 @@ // Nothing to do. } private int run(final String[] args) { private int run(final String[] args) throws LDAPToolException { // Create the command-line argument parser for use with this program. final LocalizableMessage toolDescription = INFO_LDIFDIFF_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser( LDIFDiff.class.getName(), toolDescription, false, true, 2, 2, "source target"); final ArgumentParser argParser = LDAPToolArgumentParser.builder(LDIFDiff.class.getName()) .toolDescription(toolDescription) .trailingArguments(2, "source target") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_LDIFDIFF.get()); @@ -91,91 +101,28 @@ argParser.addArgument(showUsage); argParser.setUsageArgument(showUsage, getOutputStream()); } catch (final ArgumentException ae) { final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(ae, ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage())); } // Parse the command-line arguments provided to this program. try { argParser.parseArguments(args); /* If we should just display usage or version information, then print it and exit. */ parseArguments(argParser, getErrorStream(), args); if (argParser.usageOrVersionDisplayed()) { return ResultCode.SUCCESS.intValue(); } } catch (final ArgumentException ae) { argParser.displayMessageAndUsageReference(getErrStream(), ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } InputStream sourceInputStream = null; InputStream targetInputStream = null; OutputStream outputStream = null; try { // First source file. final List<String> trailingArguments = argParser.getTrailingArguments(); if (!"-".equals(trailingArguments.get(0))) { try { sourceInputStream = new FileInputStream(trailingArguments.get(0)); } catch (final FileNotFoundException e) { final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ.get(trailingArguments.get(0), e .getLocalizedMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } sourceInputStream = getLDIFToolInputStream(this, trailingArguments.get(0)); targetInputStream = getLDIFToolInputStream(this, trailingArguments.get(1)); outputStream = getLDIFToolOutputStream(this, outputFilename); if (System.in == sourceInputStream && System.in == targetInputStream) { throw newToolParamException(ERR_LDIFDIFF_MULTIPLE_USES_OF_STDIN.get()); } // Patch file. if (!"-".equals(trailingArguments.get(1))) { try { targetInputStream = new FileInputStream(trailingArguments.get(1)); } catch (final FileNotFoundException e) { final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ.get(trailingArguments.get(1), e .getLocalizedMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } // Output file. if (outputFilename.isPresent() && !"-".equals(outputFilename.getValue())) { try { outputStream = new FileOutputStream(outputFilename.getValue()); } catch (final FileNotFoundException e) { final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_WRITE.get(outputFilename.getValue(), e .getLocalizedMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } // Default to stdin/stdout for all streams if not specified. if (sourceInputStream == null) { // Command line parameter was "-". sourceInputStream = System.in; } if (targetInputStream == null) { targetInputStream = System.in; } if (outputStream == null) { outputStream = System.out; } /* Check that we are not attempting to read both the source and target from stdin. */ if (sourceInputStream == targetInputStream) { final LocalizableMessage message = ERR_LDIFDIFF_MULTIPLE_USES_OF_STDIN.get(); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } // Perform the diff. try (LDIFEntryReader sourceReader = new LDIFEntryReader(sourceInputStream); LDIFEntryReader targetReader = new LDIFEntryReader(targetInputStream); LDIFChangeRecordWriter outputWriter = new LDIFChangeRecordWriter(outputStream)) { opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDIFModify.java
@@ -18,14 +18,15 @@ import static com.forgerock.opendj.cli.ArgumentConstants.OPTION_LONG_OUTPUT_LDIF_FILENAME; import static com.forgerock.opendj.cli.ArgumentConstants.OPTION_SHORT_OUTPUT_LDIF_FILENAME; import static com.forgerock.opendj.cli.ToolVersionHandler.newSdkVersionHandler; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolParamException; import static com.forgerock.opendj.ldap.tools.ToolsMessages.*; import static com.forgerock.opendj.cli.Utils.filterExitCode; import static com.forgerock.opendj.ldap.tools.Utils.getLDIFToolInputStream; import static com.forgerock.opendj.ldap.tools.Utils.getLDIFToolOutputStream; import static com.forgerock.opendj.ldap.tools.Utils.parseArguments; import static org.forgerock.util.Utils.closeSilently; import static com.forgerock.opendj.cli.CommonArguments.*; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -64,7 +65,14 @@ * The command-line arguments provided to this program. */ public static void main(final String[] args) { final int retCode = new LDIFModify().run(args); final LDIFModify ldifModify = new LDIFModify(); int retCode; try { retCode = ldifModify.run(args); } catch (final LDAPToolException e) { e.printErrorMessage(ldifModify); retCode = e.getResultCode(); } System.exit(filterExitCode(retCode)); } @@ -72,11 +80,13 @@ // Nothing to do. } private int run(final String[] args) { private int run(final String[] args) throws LDAPToolException { // Create the command-line argument parser for use with this program. final LocalizableMessage toolDescription = INFO_LDIFMODIFY_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser( LDIFModify.class.getName(), toolDescription, false, true, 1, 2, "source [changes]"); final ArgumentParser argParser = LDAPToolArgumentParser.builder(LDIFModify.class.getName()) .toolDescription(toolDescription) .trailingArguments(1, 2, "source [changes]") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_LDIFMODIFY.get()); @@ -100,24 +110,13 @@ argParser.addArgument(showUsage); argParser.setUsageArgument(showUsage, getOutputStream()); } catch (final ArgumentException ae) { final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(ae, ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage())); } // Parse the command-line arguments provided to this program. try { argParser.parseArguments(args); // If we should just display usage or version information, // then print it and exit. parseArguments(argParser, getErrStream(), args); if (argParser.usageOrVersionDisplayed()) { return ResultCode.SUCCESS.intValue(); } } catch (final ArgumentException ae) { argParser.displayMessageAndUsageReference(getErrStream(), ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } InputStream sourceInputStream = null; InputStream changesInputStream = null; @@ -127,68 +126,15 @@ LDIFEntryWriter outputWriter = null; try { // First source file. final List<String> trailingArguments = argParser.getTrailingArguments(); if (!"-".equals(trailingArguments.get(0))) { try { sourceInputStream = new FileInputStream(trailingArguments.get(0)); } catch (final FileNotFoundException e) { final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ.get(trailingArguments.get(0), e .getLocalizedMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } sourceInputStream = getLDIFToolInputStream(this, trailingArguments.get(0)); changesInputStream = getLDIFToolInputStream(this, trailingArguments.get(1)); outputStream = getLDIFToolOutputStream(this, outputFilename); if (System.in == sourceInputStream && System.in == changesInputStream) { throw newToolParamException(ERR_LDIFMODIFY_MULTIPLE_USES_OF_STDIN.get()); } // Patch file. if (trailingArguments.size() > 1 && !"-".equals(trailingArguments.get(1))) { try { changesInputStream = new FileInputStream(trailingArguments.get(1)); } catch (final FileNotFoundException e) { final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ.get(trailingArguments.get(1), e .getLocalizedMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } // Output file. if (outputFilename.isPresent() && !"-".equals(outputFilename.getValue())) { try { outputStream = new FileOutputStream(outputFilename.getValue()); } catch (final FileNotFoundException e) { final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_WRITE.get(outputFilename.getValue(), e .getLocalizedMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } // Default to stdin/stdout for all streams if not specified. if (sourceInputStream == null) { // Command line parameter was "-". sourceInputStream = System.in; } if (changesInputStream == null) { changesInputStream = System.in; } if (outputStream == null) { outputStream = System.out; } /* Check that we are not attempting to read both the source and changes from stdin. */ if (sourceInputStream == changesInputStream) { final LocalizableMessage message = ERR_LDIFMODIFY_MULTIPLE_USES_OF_STDIN.get(); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } // Apply the changes. sourceReader = new LDIFEntryReader(sourceInputStream); changesReader = new LDIFChangeRecordReader(changesInputStream); outputWriter = new LDIFEntryWriter(outputStream); @@ -198,8 +144,7 @@ public Entry handleDuplicateEntry(final AddRequest change, final Entry existingEntry) throws DecodeException { try { RejectedChangeRecordListener.FAIL_FAST.handleDuplicateEntry(change, existingEntry); RejectedChangeRecordListener.FAIL_FAST.handleDuplicateEntry(change, existingEntry); } catch (final DecodeException e) { logErrorOrFail(e); } @@ -210,8 +155,8 @@ public Entry handleDuplicateEntry(final ModifyDNRequest change, final Entry existingEntry, final Entry renamedEntry) throws DecodeException { try { RejectedChangeRecordListener.FAIL_FAST.handleDuplicateEntry(change, existingEntry, renamedEntry); RejectedChangeRecordListener.FAIL_FAST.handleDuplicateEntry( change, existingEntry, renamedEntry); } catch (final DecodeException e) { logErrorOrFail(e); } @@ -219,44 +164,40 @@ } @Override public void handleRejectedChangeRecord(final AddRequest change, final LocalizableMessage reason) throws DecodeException { public void handleRejectedChangeRecord( final AddRequest change, final LocalizableMessage reason) throws DecodeException { try { RejectedChangeRecordListener.FAIL_FAST.handleRejectedChangeRecord(change, reason); RejectedChangeRecordListener.FAIL_FAST.handleRejectedChangeRecord(change, reason); } catch (final DecodeException e) { logErrorOrFail(e); } } @Override public void handleRejectedChangeRecord(final DeleteRequest change, final LocalizableMessage reason) throws DecodeException { public void handleRejectedChangeRecord( final DeleteRequest change, final LocalizableMessage reason) throws DecodeException { try { RejectedChangeRecordListener.FAIL_FAST.handleRejectedChangeRecord(change, reason); RejectedChangeRecordListener.FAIL_FAST.handleRejectedChangeRecord(change, reason); } catch (final DecodeException e) { logErrorOrFail(e); } } @Override public void handleRejectedChangeRecord(final ModifyDNRequest change, final LocalizableMessage reason) throws DecodeException { public void handleRejectedChangeRecord( final ModifyDNRequest change, final LocalizableMessage reason) throws DecodeException { try { RejectedChangeRecordListener.FAIL_FAST.handleRejectedChangeRecord(change, reason); RejectedChangeRecordListener.FAIL_FAST.handleRejectedChangeRecord(change, reason); } catch (final DecodeException e) { logErrorOrFail(e); } } @Override public void handleRejectedChangeRecord(final ModifyRequest change, final LocalizableMessage reason) throws DecodeException { public void handleRejectedChangeRecord( final ModifyRequest change, final LocalizableMessage reason) throws DecodeException { try { RejectedChangeRecordListener.FAIL_FAST.handleRejectedChangeRecord(change, reason); RejectedChangeRecordListener.FAIL_FAST.handleRejectedChangeRecord(change, reason); } catch (final DecodeException e) { logErrorOrFail(e); } @@ -274,15 +215,14 @@ LDIF.copyTo(LDIF.patch(sourceReader, changesReader, listener), outputWriter); } catch (final IOException e) { if (e instanceof LocalizableException) { errPrintln(ERR_LDIFMODIFY_PATCH_FAILED.get(((LocalizableException) e) .getMessageObject())); errPrintln(ERR_LDIFMODIFY_PATCH_FAILED.get(((LocalizableException) e).getMessageObject())); } else { errPrintln(ERR_LDIFMODIFY_PATCH_FAILED.get(e.getLocalizedMessage())); } return ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue(); } finally { closeSilently(sourceReader, changesReader, outputWriter); closeSilently(sourceInputStream, changesInputStream, outputStream); closeSilently(sourceReader, changesReader, outputWriter, sourceInputStream, changesInputStream, outputStream); } return ResultCode.SUCCESS.intValue(); opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/LDIFSearch.java
@@ -17,20 +17,18 @@ import static com.forgerock.opendj.cli.ArgumentConstants.*; import static com.forgerock.opendj.cli.ToolVersionHandler.newSdkVersionHandler; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolParamException; import static com.forgerock.opendj.ldap.tools.ToolsMessages.*; import static com.forgerock.opendj.cli.Utils.filterExitCode; import static com.forgerock.opendj.cli.CommonArguments.*; import static org.forgerock.util.Utils.closeSilently; import static com.forgerock.opendj.ldap.tools.Utils.getLDIFToolInputStream; import static com.forgerock.opendj.ldap.tools.Utils.getLDIFToolOutputStream; import static com.forgerock.opendj.ldap.tools.Utils.parseArguments; import static com.forgerock.opendj.ldap.tools.Utils.readFiltersFromFile; import static com.forgerock.opendj.ldap.tools.Utils.readFilterFromString; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.LinkedList; import java.util.List; @@ -64,7 +62,14 @@ * The command-line arguments provided to this program. */ public static void main(final String[] args) { final int retCode = new LDIFSearch().run(args); final LDIFSearch ldifSearch = new LDIFSearch(); int retCode; try { retCode = ldifSearch.run(args); } catch (final LDAPToolException e) { e.printErrorMessage(ldifSearch); retCode = e.getResultCode(); } System.exit(filterExitCode(retCode)); } @@ -72,11 +77,13 @@ // Nothing to do. } private int run(final String[] args) { private int run(final String[] args) throws LDAPToolException { /* Create the command-line argument parser for use with this program. */ final LocalizableMessage toolDescription = INFO_LDIFSEARCH_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser( LDIFSearch.class.getName(), toolDescription, false, true, 1, 0, "source [filter] [attributes ...]"); final ArgumentParser argParser = LDAPToolArgumentParser.builder(LDIFSearch.class.getName()) .toolDescription(toolDescription) .trailingArgumentsUnbounded(1, "source [filter] [attributes ...]") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_LDIFSEARCH.get()); @@ -84,7 +91,7 @@ final StringArgument outputFilename; final BooleanArgument typesOnly; final IntegerArgument timeLimit; final StringArgument filename; final StringArgument filterFile; final StringArgument baseDN; final MultiChoiceArgument<SearchScope> searchScope; final IntegerArgument sizeLimit; @@ -108,12 +115,9 @@ searchScope = searchScopeArgument(); argParser.addArgument(searchScope); filename = StringArgument.builder(OPTION_LONG_FILENAME) .shortIdentifier(OPTION_SHORT_FILENAME) .description(INFO_SEARCH_DESCRIPTION_FILENAME.get()) .valuePlaceholder(INFO_FILE_PLACEHOLDER.get()) .buildAndAddToParser(argParser); filterFile = filenameArgument(INFO_SEARCH_DESCRIPTION_FILENAME.get()); argParser.addArgument(filterFile); typesOnly = BooleanArgument.builder("typesOnly") .shortIdentifier('A') @@ -138,67 +142,29 @@ argParser.addArgument(showUsage); argParser.setUsageArgument(showUsage, getOutputStream()); } catch (final ArgumentException ae) { final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(ae, ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage())); } // Parse the command-line arguments provided to this program. try { argParser.parseArguments(args); /* If we should just display usage or version information, then print it and exit. */ parseArguments(argParser, getErrorStream(), args); if (argParser.usageOrVersionDisplayed()) { return ResultCode.SUCCESS.intValue(); } } catch (final ArgumentException ae) { argParser.displayMessageAndUsageReference(getErrStream(), ERR_ERROR_PARSING_ARGS.get(ae.getMessage())); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } final List<Filter> filters = new LinkedList<>(); final List<String> attributes = new LinkedList<>(); final List<String> trailingArguments = argParser.getTrailingArguments(); if (trailingArguments.size() > 1) { final List<String> filterAndAttributeStrings = trailingArguments.subList(1, trailingArguments.size()); /* The list of trailing arguments should be structured as follow: - If a filter file is present, trailing arguments are considered as attributes - If filter file is not present, the first trailing argument is considered the filter, the other as attributes.*/ if (!filename.isPresent()) { final String filterString = filterAndAttributeStrings.remove(0); try { filters.add(Filter.valueOf(filterString)); } catch (final LocalizedIllegalArgumentException e) { errPrintln(e.getMessageObject()); return ResultCode.CLIENT_SIDE_FILTER_ERROR.intValue(); final List<String> filterAndAttributeStrings = trailingArguments.subList(1, trailingArguments.size()); // If filter file is not present, the first trailing argument is considered the filter if (!filterFile.isPresent()) { filters.add(readFilterFromString(filterAndAttributeStrings.remove(0))); } } // The rest are attributes // The rest of trailing argument are attributes attributes.addAll(filterAndAttributeStrings); } if (filename.isPresent()) { // Read the filter strings. try (BufferedReader in = new BufferedReader(new FileReader(filename.getValue()))) { String line = null; while ((line = in.readLine()) != null) { if ("".equals(line.trim())) { // ignore empty lines. continue; } filters.add(Filter.valueOf(line)); } } catch (final LocalizedIllegalArgumentException e) { errPrintln(e.getMessageObject()); return ResultCode.CLIENT_SIDE_FILTER_ERROR.intValue(); } catch (final IOException e) { errPrintln(LocalizableMessage.raw(e.toString())); return ResultCode.CLIENT_SIDE_FILTER_ERROR.intValue(); } if (filterFile.isPresent()) { filters.addAll(readFiltersFromFile(filterFile.getValue())); } if (filters.isEmpty()) { @@ -215,55 +181,13 @@ typesOnly.isPresent()).setTimeLimit(timeLimit.getIntValue()) .setSizeLimit(sizeLimit.getIntValue()); } catch (final ArgumentException | LocalizedIllegalArgumentException e) { errPrintln(e.getMessageObject()); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); throw newToolParamException(e, e.getMessageObject()); } InputStream sourceInputStream = null; OutputStream outputStream = null; try { // First source file. if (!"-".equals(trailingArguments.get(0))) { try { sourceInputStream = new FileInputStream(trailingArguments.get(0)); } catch (final FileNotFoundException e) { final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ.get(trailingArguments.get(0), e .getLocalizedMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } // Output file. if (outputFilename.isPresent() && !"-".equals(outputFilename.getValue())) { try { outputStream = new FileOutputStream(outputFilename.getValue()); } catch (final FileNotFoundException e) { final LocalizableMessage message = ERR_LDIF_FILE_CANNOT_OPEN_FOR_WRITE.get(outputFilename.getValue(), e .getLocalizedMessage()); errPrintln(message); return ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue(); } } // Default to stdin/stdout for all streams if not specified. if (sourceInputStream == null) { // Command line parameter was "-". sourceInputStream = System.in; } if (outputStream == null) { outputStream = System.out; } // Perform the search. try (LDIFEntryReader sourceReader = new LDIFEntryReader(sourceInputStream); LDIFEntryWriter outputWriter = new LDIFEntryWriter(outputStream)) { try (final LDIFEntryReader sourceReader = new LDIFEntryReader(getLDIFToolInputStream(this, trailingArguments.get(0))); final LDIFEntryWriter outputWriter = new LDIFEntryWriter(getLDIFToolOutputStream(this, outputFilename))) { LDIF.copyTo(LDIF.search(sourceReader, search), outputWriter); } } catch (final IOException e) { if (e instanceof LocalizableException) { errPrintln(ERR_LDIFSEARCH_FAILED.get(((LocalizableException) e).getMessageObject())); @@ -271,8 +195,6 @@ errPrintln(ERR_LDIFSEARCH_FAILED.get(e.getLocalizedMessage())); } return ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue(); } finally { closeSilently(sourceInputStream, outputStream); } return ResultCode.SUCCESS.intValue(); opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/MakeLDIF.java
@@ -17,6 +17,7 @@ package com.forgerock.opendj.ldap.tools; import static com.forgerock.opendj.cli.ArgumentConstants.*; import static com.forgerock.opendj.cli.CommonArguments.showUsageArgument; import static com.forgerock.opendj.cli.ToolVersionHandler.newSdkVersionHandler; import static com.forgerock.opendj.ldap.tools.ToolsMessages.*; import static com.forgerock.opendj.cli.Utils.filterExitCode; @@ -70,8 +71,10 @@ /** Run Make LDIF with provided command-line arguments. */ int run(final String[] args) { final LocalizableMessage toolDescription = INFO_MAKELDIF_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser(MakeLDIF.class.getName(), toolDescription, false, true, 1, 1, "template-file-path"); final ArgumentParser argParser = LDAPToolArgumentParser.builder(MakeLDIF.class.getName()) .toolDescription(toolDescription) .trailingArguments(1, "template-file-path") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_MAKELDIF.get()); argParser.setDocToolDescriptionSupplement(SUPPLEMENT_DESCRIPTION_MAKELDIF.get()); @@ -110,11 +113,9 @@ .multiValued() .valuePlaceholder(INFO_CONSTANT_PLACEHOLDER.get()) .buildAndAddToParser(argParser); showUsage = BooleanArgument.builder(OPTION_LONG_HELP) .shortIdentifier(OPTION_SHORT_HELP) .description(INFO_MAKELDIF_DESCRIPTION_HELP.get()) .buildAndAddToParser(argParser); showUsage = showUsageArgument(); argParser.addArgument(showUsage); wrapColumn = IntegerArgument.builder("wrapColumn") opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ModRate.java
@@ -150,9 +150,10 @@ private int run(final String[] args) { // Creates the command-line argument parser for use with this program final LocalizableMessage toolDescription = INFO_MODRATE_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser(ModRate.class.getName(), toolDescription, false, true, 1, 0, "[(attribute:value format string) ...]"); final ArgumentParser argParser = LDAPToolArgumentParser.builder(ModRate.class.getName()) .toolDescription(toolDescription) .trailingArgumentsUnbounded(1, "[(attribute:value format string) ...]") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_MODRATE.get()); argParser.setDocToolDescriptionSupplement(SUPPLEMENT_DESCRIPTION_RATE_TOOLS.get()); @@ -194,11 +195,8 @@ argParser.addArgument(showUsage); argParser.setUsageArgument(showUsage, getOutputStream()); scriptFriendly = BooleanArgument.builder("scriptFriendly") .shortIdentifier('S') .description(INFO_DESCRIPTION_SCRIPT_FRIENDLY.get()) .buildAndAddToParser(argParser); scriptFriendly = scriptFriendlySdkArgument(); argParser.addArgument(scriptFriendly); } catch (final ArgumentException ae) { final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); errPrintln(message); opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/SearchRate.java
@@ -196,9 +196,10 @@ private int run(final String[] args) { // Create the command-line argument parser for use with this program. final LocalizableMessage toolDescription = INFO_SEARCHRATE_TOOL_DESCRIPTION.get(); final ArgumentParser argParser = new ArgumentParser(SearchRate.class.getName(), toolDescription, false, true, 1, 0, "[filter format string] [attributes ...]"); final ArgumentParser argParser = LDAPToolArgumentParser.builder(SearchRate.class.getName()) .toolDescription(toolDescription) .trailingArgumentsUnbounded(1, "[filter format string] [attributes ...]") .build(); argParser.setVersionHandler(newSdkVersionHandler()); argParser.setShortToolDescription(REF_SHORT_DESC_SEARCHRATE.get()); argParser.setDocToolDescriptionSupplement(SUPPLEMENT_DESCRIPTION_RATE_TOOLS.get()); @@ -254,11 +255,8 @@ verbose = verboseArgument(); argParser.addArgument(verbose); scriptFriendly = BooleanArgument.builder("scriptFriendly") .shortIdentifier('S') .description(INFO_DESCRIPTION_SCRIPT_FRIENDLY.get()) .buildAndAddToParser(argParser); scriptFriendly = scriptFriendlySdkArgument(); argParser.addArgument(scriptFriendly); } catch (final ArgumentException ae) { final LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()); errPrintln(message); opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/Utils.java
@@ -16,17 +16,47 @@ */ package com.forgerock.opendj.ldap.tools; import static com.forgerock.opendj.cli.ArgumentConstants.USE_SYSTEM_STREAM_TOKEN; import static com.forgerock.opendj.cli.Utils.readBytesFromFile; import static com.forgerock.opendj.cli.Utils.secondsToTimeString; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolException; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolExceptionAlreadyPrinted; import static com.forgerock.opendj.ldap.tools.LDAPToolException.newToolParamException; import static com.forgerock.opendj.ldap.tools.ToolsMessages.*; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import com.forgerock.opendj.cli.ArgumentException; import com.forgerock.opendj.cli.ArgumentParser; import com.forgerock.opendj.cli.BooleanArgument; import com.forgerock.opendj.cli.IntegerArgument; import com.forgerock.opendj.cli.StringArgument; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.LocalizableMessageDescriptor; import org.forgerock.i18n.LocalizedIllegalArgumentException; import org.forgerock.opendj.ldap.ByteString; import org.forgerock.opendj.ldap.Connection; import org.forgerock.opendj.ldap.ConnectionFactory; import org.forgerock.opendj.ldap.DecodeException; import org.forgerock.opendj.ldap.DecodeOptions; import org.forgerock.opendj.ldap.Filter; import org.forgerock.opendj.ldap.LdapException; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.controls.AssertionRequestControl; import org.forgerock.opendj.ldap.controls.AuthorizationIdentityRequestControl; import org.forgerock.opendj.ldap.controls.AuthorizationIdentityResponseControl; import org.forgerock.opendj.ldap.controls.Control; import org.forgerock.opendj.ldap.controls.GenericControl; import org.forgerock.opendj.ldap.controls.GetEffectiveRightsRequestControl; import org.forgerock.opendj.ldap.controls.PasswordExpiredResponseControl; @@ -36,116 +66,26 @@ import org.forgerock.opendj.ldap.controls.PasswordPolicyResponseControl; import org.forgerock.opendj.ldap.controls.PasswordPolicyWarningType; import org.forgerock.opendj.ldap.controls.SubtreeDeleteRequestControl; import org.forgerock.opendj.ldap.requests.BindRequest; import org.forgerock.opendj.ldap.requests.Request; import org.forgerock.opendj.ldap.responses.BindResult; import com.forgerock.opendj.cli.ConsoleApplication; import com.forgerock.opendj.ldap.controls.AccountUsabilityRequestControl; import com.forgerock.opendj.util.StaticUtils; import org.forgerock.opendj.ldap.responses.Result; /** * This class provides utility functions for all the client side tools. */ final class Utils { /** * Parse the specified command line argument to create the appropriate * LDAPControl. The argument string should be in the format * controloid[:criticality[:value|::b64value|:<fileurl]] * * @param argString * The argument string containing the encoded control * information. * @return The control decoded from the provided string, or * <CODE>null</CODE> if an error occurs while parsing the argument * value. * @throws org.forgerock.opendj.ldap.DecodeException * If an error occurs. */ static GenericControl getControl(final String argString) throws DecodeException { String controlOID = null; boolean controlCriticality = false; ByteString controlValue = null; int idx = argString.indexOf(":"); if (idx < 0) { controlOID = argString; } else { controlOID = argString.substring(0, idx); static int printErrorMessage(final ConsoleApplication app, final LdapException ldapException) { return printErrorMessage(app, ldapException, null); } final String lowerOID = StaticUtils.toLowerCase(controlOID); if ("accountusable".equals(lowerOID) || "accountusability".equals(lowerOID)) { controlOID = AccountUsabilityRequestControl.OID; } else if ("authzid".equals(lowerOID) || "authorizationidentity".equals(lowerOID)) { controlOID = AuthorizationIdentityRequestControl.OID; } else if ("noop".equals(lowerOID) || "no-op".equals(lowerOID)) { // controlOID = OID_LDAP_NOOP_OPENLDAP_ASSIGNED; } else if ("subentries".equals(lowerOID)) { // controlOID = OID_LDAP_SUBENTRIES; } else if ("managedsait".equals(lowerOID)) { // controlOID = OID_MANAGE_DSAIT_CONTROL; } else if ("pwpolicy".equals(lowerOID) || "passwordpolicy".equals(lowerOID)) { controlOID = PasswordPolicyRequestControl.OID; } else if ("subtreedelete".equals(lowerOID) || "treedelete".equals(lowerOID)) { controlOID = SubtreeDeleteRequestControl.OID; } else if ("realattrsonly".equals(lowerOID) || "realattributesonly".equals(lowerOID)) { // controlOID = OID_REAL_ATTRS_ONLY; } else if ("virtualattrsonly".equals(lowerOID) || "virtualattributesonly".equals(lowerOID)) { // controlOID = OID_VIRTUAL_ATTRS_ONLY; } else if ("effectiverights".equals(lowerOID) || "geteffectiverights".equals(lowerOID)) { controlOID = GetEffectiveRightsRequestControl.OID; } if (idx < 0) { return GenericControl.newControl(controlOID); } final String remainder = argString.substring(idx + 1, argString.length()); idx = remainder.indexOf(":"); if (idx == -1) { if ("true".equalsIgnoreCase(remainder)) { controlCriticality = true; } else if ("false".equalsIgnoreCase(remainder)) { controlCriticality = false; } else { // TODO: I18N throw DecodeException.error(LocalizableMessage .raw("Invalid format for criticality value:" + remainder)); } return GenericControl.newControl(controlOID, controlCriticality); } final String critical = remainder.substring(0, idx); if ("true".equalsIgnoreCase(critical)) { controlCriticality = true; } else if ("false".equalsIgnoreCase(critical)) { controlCriticality = false; } else { // TODO: I18N throw DecodeException.error(LocalizableMessage .raw("Invalid format for criticality value:" + critical)); } final String valString = remainder.substring(idx + 1, remainder.length()); if (valString.charAt(0) == ':') { controlValue = ByteString.valueOfBase64(valString.substring(1, valString.length())); } else if (valString.charAt(0) == '<') { // Read data from the file. final String filePath = valString.substring(1, valString.length()); try { final byte[] val = readBytesFromFile(filePath); controlValue = ByteString.wrap(val); } catch (final Exception e) { return null; } } else { controlValue = ByteString.valueOfUtf8(valString); } return GenericControl.newControl(controlOID, controlCriticality, controlValue); static int printErrorMessage(final ConsoleApplication app, final LdapException ldapException, final LocalizableMessageDescriptor.Arg2<Number, Object> errorMsg) { return printErrorMessage(app, ldapException.getResult(), errorMsg); } /** @@ -154,34 +94,41 @@ * * @param app * The console app to use to write the error message. * @param ere * @param result * The error result. * @param errorMsg * The error message associated to the application to use to display error result code and label. * @return The error code. */ static int printErrorMessage(final ConsoleApplication app, final LdapException ere) { /* if ((ere.getMessage() != null) && (ere.getMessage().length() > 0)) { app.println(LocalizableMessage.raw(ere.getMessage())); }*/ static int printErrorMessage(final ConsoleApplication app, final Result result, final LocalizableMessageDescriptor.Arg2<Number, Object> errorMsg) { final ResultCode resultCode = result.getResultCode(); final int rc = resultCode.intValue(); if (ere.getResult().getResultCode().intValue() >= 0) { app.errPrintln(ERR_TOOL_RESULT_CODE.get(ere.getResult().getResultCode().intValue(), ere .getResult().getResultCode().toString())); if (rc != ResultCode.UNDEFINED.intValue() && errorMsg != null) { app.errPrintln(errorMsg.get(rc, resultCode.toString())); } printlnTextMsg(app, ERR_TOOL_ERROR_MESSAGE, result.getDiagnosticMessage()); printlnTextMsg(app, ERR_TOOL_MATCHED_DN, result.getMatchedDN()); final Throwable cause = result.getCause(); if (app.isVerbose() && cause != null) { cause.printStackTrace(app.getErrorStream()); } if (ere.getResult().getDiagnosticMessage() != null && ere.getResult().getDiagnosticMessage().length() > 0) { app.errPrintln(ERR_TOOL_ERROR_MESSAGE.get(ere.getResult().getDiagnosticMessage())); return rc; } if (ere.getResult().getMatchedDN() != null && ere.getResult().getMatchedDN().length() > 0) { app.errPrintln(ERR_TOOL_MATCHED_DN.get(ere.getResult().getMatchedDN())); static void printSuccessMessage( final ConsoleApplication app, final Result r, final String operationType, final String dn) { app.println(INFO_OPERATION_SUCCESSFUL.get(operationType, dn)); printlnTextMsg(app, r.getDiagnosticMessage()); final List<String> referralURIs = r.getReferralURIs(); if (referralURIs != null) { for (final String uri : referralURIs) { app.println(LocalizableMessage.raw(uri)); } if (app.isVerbose() && ere.getResult().getCause() != null) { ere.getResult().getCause().printStackTrace(app.getErrorStream()); } return ere.getResult().getResultCode().intValue(); } static void printPasswordPolicyResults(final ConsoleApplication app, final BindResult result) { @@ -196,8 +143,8 @@ } try { final PasswordExpiredResponseControl control = result.getControl(PasswordExpiredResponseControl.DECODER, new DecodeOptions()); final PasswordExpiredResponseControl control = result.getControl( PasswordExpiredResponseControl.DECODER, new DecodeOptions()); if (control != null) { app.println(INFO_BIND_PASSWORD_EXPIRED.get()); } @@ -206,40 +153,60 @@ } try { final PasswordExpiringResponseControl control = result.getControl(PasswordExpiringResponseControl.DECODER, new DecodeOptions()); final PasswordExpiringResponseControl control = result.getControl( PasswordExpiringResponseControl.DECODER, new DecodeOptions()); if (control != null) { final LocalizableMessage timeString = secondsToTimeString(control.getSecondsUntilExpiration()); app.println(INFO_BIND_PASSWORD_EXPIRING.get(timeString)); app.println(INFO_BIND_PASSWORD_EXPIRING.get(secondsToTimeString(control.getSecondsUntilExpiration()))); } } catch (final DecodeException e) { app.errPrintln(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); } try { final PasswordPolicyResponseControl control = result.getControl(PasswordPolicyResponseControl.DECODER, new DecodeOptions()); final PasswordPolicyResponseControl control = result.getControl( PasswordPolicyResponseControl.DECODER, new DecodeOptions()); if (control != null) { final PasswordPolicyErrorType errorType = control.getErrorType(); if (errorType == PasswordPolicyErrorType.PASSWORD_EXPIRED) { printPasswordPolicyError(control.getErrorType(), app); printPasswordPolicyWarning(control.getWarningType(), control.getWarningValue(), app); } } catch (final DecodeException e) { app.errPrintln(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); } } private static void printPasswordPolicyError(final PasswordPolicyErrorType errorType, final ConsoleApplication app) { if (errorType == null) { return; } switch (errorType) { case PASSWORD_EXPIRED: app.println(INFO_BIND_PASSWORD_EXPIRED.get()); } else if (errorType == PasswordPolicyErrorType.ACCOUNT_LOCKED) { break; case ACCOUNT_LOCKED: app.println(INFO_BIND_ACCOUNT_LOCKED.get()); } else if (errorType == PasswordPolicyErrorType.CHANGE_AFTER_RESET) { break; case CHANGE_AFTER_RESET: app.println(INFO_BIND_MUST_CHANGE_PASSWORD.get()); break; } } final PasswordPolicyWarningType warningType = control.getWarningType(); if (warningType == PasswordPolicyWarningType.TIME_BEFORE_EXPIRATION) { final LocalizableMessage timeString = secondsToTimeString(control.getWarningValue()); app.println(INFO_BIND_PASSWORD_EXPIRING.get(timeString)); } else if (warningType == PasswordPolicyWarningType.GRACE_LOGINS_REMAINING) { app.println(INFO_BIND_GRACE_LOGINS_REMAINING.get(control.getWarningValue())); private static void printPasswordPolicyWarning(final PasswordPolicyWarningType warningType, final int warningValue, final ConsoleApplication app) { if (warningType == null) { return; } } } catch (final DecodeException e) { app.errPrintln(ERR_DECODE_CONTROL_FAILURE.get(e.getLocalizedMessage())); switch (warningType) { case TIME_BEFORE_EXPIRATION: app.println(INFO_BIND_PASSWORD_EXPIRING.get(secondsToTimeString(warningValue))); break; case GRACE_LOGINS_REMAINING: app.println(INFO_BIND_GRACE_LOGINS_REMAINING.get(warningValue)); break; } } @@ -260,6 +227,230 @@ } } static List<Filter> readFiltersFromFile(final String fileName) throws LDAPToolException { final List<Filter> filters = new ArrayList<>(); try (final BufferedReader in = new BufferedReader(new FileReader(fileName))) { String line; while ((line = in.readLine()) != null) { if ("".equals(line.trim())) { // ignore empty lines. continue; } filters.add(Filter.valueOf(line)); } return filters; } catch (final IOException e) { throw newToolException(e, ResultCode.CLIENT_SIDE_FILTER_ERROR, LocalizableMessage.raw(e.toString())); } catch (final LocalizedIllegalArgumentException e) { throw newToolException(e, ResultCode.CLIENT_SIDE_FILTER_ERROR, e.getMessageObject()); } } static Filter readFilterFromString(final String filterStr) throws LDAPToolException { try { return Filter.valueOf(filterStr); } catch (final LocalizedIllegalArgumentException e) { throw newToolException(e, ResultCode.CLIENT_SIDE_FILTER_ERROR, e.getMessageObject()); } } static void parseArguments(final ArgumentParser argParser, final PrintStream stream, final String[] args) throws LDAPToolException { try { argParser.parseArguments(args); } catch (final ArgumentException e) { argParser.displayMessageAndUsageReference(stream, ERR_ERROR_PARSING_ARGS.get(e.getMessage())); throw newToolExceptionAlreadyPrinted(e, ResultCode.CLIENT_SIDE_PARAM_ERROR); } } static InputStream getLDIFToolInputStream(final ConsoleApplication app, final String filePath) throws LDAPToolException { if (!USE_SYSTEM_STREAM_TOKEN.equals(filePath)) { try { return new FileInputStream(filePath); } catch (final FileNotFoundException e) { throw newToolParamException( e, ERR_LDIF_FILE_CANNOT_OPEN_FOR_READ.get(filePath, e.getLocalizedMessage())); } } else { return app.getInputStream(); } } static OutputStream getLDIFToolOutputStream(final ConsoleApplication app, final StringArgument outputFileArg) throws LDAPToolException { final String filePath = outputFileArg.getValue(); if (outputFileArg.isPresent() && !USE_SYSTEM_STREAM_TOKEN.equals(filePath)) { try { return new FileOutputStream(filePath); } catch (final FileNotFoundException e) { throw newToolParamException( e, ERR_LDIF_FILE_CANNOT_OPEN_FOR_WRITE.get(filePath, e.getLocalizedMessage())); } } else { return app.getOutputStream(); } } static void ensureLdapProtocolVersionIsSupported(final IntegerArgument version) throws LDAPToolException { try { final int versionNumber = version.getIntValue(); if (versionNumber != 2 && versionNumber != 3) { throw newToolParamException(ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(versionNumber))); } } catch (final ArgumentException e) { throw newToolParamException(e, ERR_DESCRIPTION_INVALID_VERSION.get(String.valueOf(version.getValue()))); } } static void addControlsToRequest(final Request request, final List<Control> controls) throws LDAPToolException { for (final Control control : controls) { request.addControl(control); } } static List<Control> readControls(final StringArgument controlArg) throws LDAPToolException { final List<Control> controls = new LinkedList<>(); if (controlArg.isPresent()) { for (final String ctrlString : controlArg.getValues()) { try { controls.add(getControl(ctrlString)); } catch (final DecodeException e) { throw newToolParamException(e, ERR_TOOL_INVALID_CONTROL_STRING.get(ctrlString)); } } } return controls; } /** * Parse the specified command line argument to create the appropriate * LDAPControl. The argument string should be in the format * controloid[:criticality[:value|::b64value|:<fileurl]] * * @param argString * The argument string containing the encoded control * information. * @return The control decoded from the provided string, or * <CODE>null</CODE> if an error occurs while parsing the argument * value. * @throws org.forgerock.opendj.ldap.DecodeException * If an error occurs. */ private static GenericControl getControl(final String argString) throws DecodeException { final String[] control = argString.split(":"); final int nbControlElements = control.length; final String controlOID = readControlID(control[0]); if (nbControlElements == 1) { return GenericControl.newControl(controlOID); } final boolean critic = readControlCriticality(control[1], argString); if (nbControlElements == 2) { return GenericControl.newControl(controlOID, critic); } final ByteString controlValue; if (control[2].isEmpty()) { controlValue = ByteString.valueOfBase64(control[3]); } else if (control[2].startsWith("<")) { // Read data from the file. try { controlValue = ByteString.wrap(readBytesFromFile(control[2].substring(1))); } catch (final Exception e) { return null; } } else { controlValue = ByteString.valueOfUtf8(control[2]); } return GenericControl.newControl(controlOID, critic, controlValue); } private static String readControlID(final String controlOidStr) { switch (controlOidStr.toLowerCase()) { case "accountusable": case "accountusability": return AccountUsabilityRequestControl.OID; case "authzid": case "authorizationidentity": return AuthorizationIdentityRequestControl.OID; case "pwpolicy": case "passwordpolicy": return PasswordPolicyRequestControl.OID; case "treedelete": case "subtreedelete": return SubtreeDeleteRequestControl.OID; case "effectiverights": case "geteffectiverights": return GetEffectiveRightsRequestControl.OID; case "noop": case "no-op": case "subentries": case "managedsait": case "realattributesonly": case "realattrsonly": case "virtualattributesonly": case "virtualattrsonly": default: // TODO Support these request controls once migrated in the sdk return controlOidStr; } } private static boolean readControlCriticality(final String criticalityStr, final String controlStr) throws DecodeException { if ("true".equalsIgnoreCase(criticalityStr)) { return true; } else if ("false".equalsIgnoreCase(criticalityStr)) { return false; } else { throw DecodeException.error(ERR_DECODE_CONTROL_CRITICALITY.get(criticalityStr, controlStr)); } } static Control readAssertionControl(final String assertionFilter) throws LDAPToolException { try { // FIXME -- Change this to the correct OID when the official one is assigned. return AssertionRequestControl.newControl(true, Filter.valueOf(assertionFilter)); } catch (final LocalizedIllegalArgumentException e) { throw newToolParamException(e, ERR_LDAP_ASSERTION_INVALID_FILTER.get(e.getMessage())); } } static Connection getConnection(final ConnectionFactory connectionFactory, final BindRequest bindRequest, final BooleanArgument dryRunArg, final ConsoleApplication app) throws LDAPToolException { if (!dryRunArg.isPresent()) { try { final Connection connection = connectionFactory.getConnection(); if (bindRequest != null) { printPasswordPolicyResults(app, connection.bind(bindRequest)); } return connection; } catch (final LdapException e) { printErrorMessage(app, e, ERR_LDAPP_BIND_FAILED); throw newToolExceptionAlreadyPrinted(e, e.getResult().getResultCode()); } } return null; } static void printlnTextMsg(final ConsoleApplication app, final String msg) { printlnTextMsg(app, null, msg); } static void printlnTextMsg(final ConsoleApplication app, final LocalizableMessageDescriptor.Arg1<Object> localizableMsg, final String msg) { if (msg != null && !msg.isEmpty()) { app.errPrintln(localizableMsg == null ? LocalizableMessage.raw(msg) : localizableMsg.get(msg)); } } /** Prevent instantiation. */ private Utils() { // Do nothing. opendj-ldap-toolkit/src/main/resources/com/forgerock/opendj/ldap/tools/tools.properties
@@ -106,8 +106,6 @@ the target user INFO_LDAPPWMOD_DESCRIPTION_CURRENTPWFILE=Path to a file \ containing the current password for the target user ERR_LDAPPWMOD_CONFLICTING_ARGS=The %s and %s arguments may not be \ provided together ERR_LDAPPWMOD_FAILED=The LDAP password modify operation failed: \ %d (%s) ERR_LDAPPWMOD_FAILURE_ERROR_MESSAGE=Error Message: %s @@ -296,6 +294,7 @@ INFO_TOOL_WARMING_UP=Warming up for %d seconds... ERR_AUTHRATE_NO_BIND_DN_PROVIDED=Authentication information must be provided \ to use this tool ERR_DECODE_CONTROL_CRITICALITY=Invalid format for criticality value '%s' in control '%s' # # MakeLDIF tool # @@ -309,7 +308,6 @@ INFO_MAKELDIF_DESCRIPTION_LDIF=The path to the LDIF file to be written INFO_MAKELDIF_DESCRIPTION_SEED=The seed to use to initialize the random \ number generator INFO_MAKELDIF_DESCRIPTION_HELP=Show this usage information INFO_MAKELDIF_DESCRIPTION_RESOURCE_PATH=Path to look for \ MakeLDIF resources (e.g., data files) INFO_MAKELDIF_PROCESSED_N_ENTRIES=Processed %d entries @@ -326,6 +324,10 @@ INFO_MAKELDIF_DESCRIPTION_WRAP_COLUMN=Maximum length of an output line \ (0 for no wrapping) INFO_MAKELDIF_WRAP_COLUMN_PLACEHOLDER={wrapColumn} ERR_LDAPP_BIND_FAILED=The LDAP bind request failed: %d (%s) ERR_LDAP_SEARCH_FAILED=The LDAP search request failed: %d (%s) ERR_LDAP_MODIFY_FAILED=The LDAP modify request failed: %d (%s) ERR_LDAP_COMPARE_FAILED=The LDAP compare request failed: %d (%s) # # AddRate Tool # opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPCompareITCase.java
@@ -88,6 +88,8 @@ LDAPCompare ldapCompare = new LDAPCompare(outStream, errStream); ldapCompare.run(arguments); checkOuputStreams(out, err, expectedOut, expectedErr); } catch (final LDAPToolException ae) { checkOuputStreams(out, err, expectedOut, expectedErr); } } opendj-ldap-toolkit/src/test/java/com/forgerock/opendj/ldap/tools/LDAPSearchITCase.java
@@ -81,6 +81,8 @@ PrintStream errStream = new PrintStream(err.asOutputStream())) { LDAPSearch ldapSearch = new LDAPSearch(outStream, errStream); ldapSearch.run(arguments); checkOuputStreams(out, err, expectedOut, expectedErr); } catch (final LDAPToolException e) { checkOuputStreams(out, err, expectedOut, expectedErr); } } opendj-server-legacy/src/main/java/org/opends/server/tools/makeldif/MakeLDIFInputStream.java
@@ -65,14 +65,6 @@ /** The queue used to hold generated entries until they can be read. */ private LinkedBlockingQueue<TemplateEntry> entryQueue; /** The background thread being used to actually generate the entries. */ private MakeLDIFInputStreamThread generatorThread; /** The template file to use to generate the entries. */ private TemplateFile templateFile; /** * Creates a new MakeLDIF input stream that will generate entries based on the * provided template file. @@ -81,8 +73,6 @@ */ public MakeLDIFInputStream(TemplateFile templateFile) { this.templateFile = templateFile; allGenerated = false; closed = false; entryQueue = new LinkedBlockingQueue<>(10); @@ -102,8 +92,8 @@ ioException = ioe; } generatorThread = new MakeLDIFInputStreamThread(this, templateFile); generatorThread.start(); /* The background thread being used to actually generate the entries. */ new MakeLDIFInputStreamThread(this, templateFile).start(); }