001/* 002 * Copyright 2010-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2010-2020 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2010-2020 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk.unboundidds; 037 038 039 040import java.io.OutputStream; 041import java.io.PrintStream; 042import java.lang.reflect.Constructor; 043import java.util.Arrays; 044import java.util.List; 045 046import com.unboundid.ldap.listener.InMemoryDirectoryServerTool; 047import com.unboundid.ldap.sdk.LDAPException; 048import com.unboundid.ldap.sdk.ResultCode; 049import com.unboundid.ldap.sdk.Version; 050import com.unboundid.ldap.sdk.examples.AuthRate; 051import com.unboundid.ldap.sdk.examples.Base64Tool; 052import com.unboundid.ldap.sdk.examples.IdentifyReferencesToMissingEntries; 053import com.unboundid.ldap.sdk.examples.IdentifyUniqueAttributeConflicts; 054import com.unboundid.ldap.sdk.examples.IndentLDAPFilter; 055import com.unboundid.ldap.sdk.examples.LDAPDebugger; 056import com.unboundid.ldap.sdk.examples.ModRate; 057import com.unboundid.ldap.sdk.examples.SearchRate; 058import com.unboundid.ldap.sdk.examples.SearchAndModRate; 059import com.unboundid.ldap.sdk.examples.TestLDAPSDKPerformance; 060import com.unboundid.ldap.sdk.examples.ValidateLDIF; 061import com.unboundid.ldap.sdk.persist.GenerateSchemaFromSource; 062import com.unboundid.ldap.sdk.persist.GenerateSourceFromSchema; 063import com.unboundid.ldap.sdk.schema.ValidateLDAPSchema; 064import com.unboundid.ldap.sdk.transformations.TransformLDIF; 065import com.unboundid.ldap.sdk.unboundidds.examples.DumpDNs; 066import com.unboundid.ldap.sdk.unboundidds.examples.SubtreeAccessibility; 067import com.unboundid.ldap.sdk.unboundidds.examples.SummarizeAccessLog; 068import com.unboundid.ldap.sdk.unboundidds.tools.CollectSupportData; 069import com.unboundid.ldap.sdk.unboundidds.tools.GenerateTOTPSharedSecret; 070import com.unboundid.ldap.sdk.unboundidds.tools.LDAPCompare; 071import com.unboundid.ldap.sdk.unboundidds.tools.LDAPDelete; 072import com.unboundid.ldap.sdk.unboundidds.tools.LDAPModify; 073import com.unboundid.ldap.sdk.unboundidds.tools.LDAPPasswordModify; 074import com.unboundid.ldap.sdk.unboundidds.tools.LDAPSearch; 075import com.unboundid.ldap.sdk.unboundidds.tools.ManageAccount; 076import com.unboundid.ldap.sdk.unboundidds.tools.SplitLDIF; 077import com.unboundid.ldif.LDIFDiff; 078import com.unboundid.ldif.LDIFModify; 079import com.unboundid.ldif.LDIFSearch; 080import com.unboundid.util.CommandLineTool; 081import com.unboundid.util.Debug; 082import com.unboundid.util.NotNull; 083import com.unboundid.util.Nullable; 084import com.unboundid.util.StaticUtils; 085import com.unboundid.util.ThreadSafety; 086import com.unboundid.util.ThreadSafetyLevel; 087import com.unboundid.util.ssl.TLSCipherSuiteSelector; 088import com.unboundid.util.ssl.cert.ManageCertificates; 089 090import static com.unboundid.ldap.sdk.unboundidds.UnboundIDDSMessages.*; 091 092 093 094/** 095 * This class provides an entry point that may be used to launch other tools 096 * provided as part of the LDAP SDK. This is primarily a convenience for 097 * someone who just has the jar file and none of the scripts, since you can run 098 * "<CODE>java -jar unboundid-ldapsdk.jar {tool-name} {tool-args}</CODE>" 099 * in order to invoke any of the example tools. Running just 100 * "<CODE>java -jar unboundid-ldapsdk.jar</CODE>" will display version 101 * information about the LDAP SDK. 102 * <BR> 103 * <BLOCKQUOTE> 104 * <B>NOTE:</B> This class, and other classes within the 105 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 106 * supported for use against Ping Identity, UnboundID, and 107 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 108 * for proprietary functionality or for external specifications that are not 109 * considered stable or mature enough to be guaranteed to work in an 110 * interoperable way with other types of LDAP servers. 111 * </BLOCKQUOTE> 112 * <BR> 113 * The tool names are case-insensitive. Supported tool names include: 114 * <UL> 115 * <LI>authrate -- Launch the {@link AuthRate} tool.</LI> 116 * <LI>base64 -- Launch the {@link Base64Tool} tool.</LI> 117 * <LI>collect-support-data -- Launch the 118 * {@link CollectSupportData} tool.</LI> 119 * <LI>deliver-one-time-password -- Launch the 120 * {@link DeliverOneTimePassword} tool.</LI> 121 * <LI>deliver-password-reset-token -- Launch the 122 * {@link DeliverPasswordResetToken} tool.</LI> 123 * <LI>dump-dns -- Launch the {@link DumpDNs} tool.</LI> 124 * <LI>generate-schema-from-source -- Launch the 125 * {@link GenerateSchemaFromSource} tool.</LI> 126 * <LI>generate-source-from-schema -- Launch the 127 * {@link GenerateSourceFromSchema} tool.</LI> 128 * <LI>generate-totp-shared-secret -- Launch the 129 * {@link GenerateTOTPSharedSecret} tool.</LI> 130 * <LI>identify-references-to-missing-entries -- Launch the 131 * {@link IdentifyReferencesToMissingEntries} tool.</LI> 132 * <LI>identify-unique-attribute-conflicts -- Launch the 133 * {@link IdentifyUniqueAttributeConflicts} tool.</LI> 134 * <LI>indent-ldap-filter -- Launch the {@link IndentLDAPFilter} tool.</LI> 135 * <LI>in-memory-directory-server -- Launch the 136 * {@link InMemoryDirectoryServerTool} tool.</LI> 137 * <LI>ldapcompare -- Launch the {@link LDAPCompare} tool.</LI> 138 * <LI>ldapdelete -- Launch the {@link LDAPDelete} tool.</LI> 139 * <LI>ldapmodify -- Launch the {@link LDAPModify} tool.</LI> 140 * <LI>ldappasswordmodify -- Launch the {@link LDAPPasswordModify} tool.</LI> 141 * <LI>ldapsearch -- Launch the {@link LDAPSearch} tool.</LI> 142 * <LI>ldap-debugger -- Launch the {@link LDAPDebugger} tool.</LI> 143 * <LI>ldifmodify -- Launch the {@link LDIFModify} tool.</LI> 144 * <LI>ldifsearch -- Launch the {@link LDIFSearch} tool.</LI> 145 * <LI>ldif-diff -- Launch the {@link LDIFDiff} tool.</LI> 146 * <LI>manage-account -- Launch the {@link ManageAccount} tool.</LI> 147 * <LI>manage-certificates -- Launch the {@link ManageCertificates} tool.</LI> 148 * <LI>modrate -- Launch the {@link ModRate} tool.</LI> 149 * <LI>move-subtree -- Launch the {@link MoveSubtree} tool.</LI> 150 * <LI>register-yubikey-otp-device -- Launch the 151 * {@link RegisterYubiKeyOTPDevice} tool.</LI> 152 * <LI>searchrate -- Launch the {@link SearchRate} tool.</LI> 153 * <LI>search-and-mod-rate -- Launch the {@link SearchAndModRate} tool.</LI> 154 * <LI>split-ldif -- Launch the {@link SplitLDIF} tool.</LI> 155 * <LI>subtree-accessibility -- Launch the {@link SubtreeAccessibility} 156 * tool.</LI> 157 * <LI>summarize-access-log -- Launch the {@link SummarizeAccessLog} 158 * tool.</LI> 159 * <LI>test-ldap-sdk-performance -- Launch the {@link TLSCipherSuiteSelector} 160 * tool.</LI> 161 * <LI>tls-cipher-suite-selector -- Launch the {@link TLSCipherSuiteSelector} 162 * tool.</LI> 163 * <LI>transform-ldif -- Launch the {@link TransformLDIF} tool.</LI> 164 * <LI>validate-ldap-schema -- Launch the {@link ValidateLDAPSchema} 165 * tool.</LI> 166 * <LI>validate-ldif -- Launch the {@link ValidateLDIF} tool.</LI> 167 * <LI>version -- Display version information for the LDAP SDK.</LI> 168 * </UL> 169 */ 170@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 171public final class Launcher 172{ 173 /** 174 * Prevent this utility class from being instantiated. 175 */ 176 private Launcher() 177 { 178 // No implementation required. 179 } 180 181 182 183 /** 184 * Parses the command-line arguments and performs any appropriate processing 185 * for this program. 186 * 187 * @param args The command-line arguments provided to this program. 188 */ 189 public static void main(@NotNull final String... args) 190 { 191 main(System.out, System.err, args); 192 } 193 194 195 196 /** 197 * Parses the command-line arguments and performs any appropriate processing 198 * for this program. 199 * 200 * @param outStream The output stream to which standard out should be 201 * written. It may be {@code null} if output should be 202 * suppressed. 203 * @param errStream The output stream to which standard error should be 204 * written. It may be {@code null} if error messages 205 * should be suppressed. 206 * @param args The command-line arguments provided to this program. 207 * 208 * @return A result code with information about the status of processing. 209 */ 210 @NotNull() 211 public static ResultCode main(@Nullable final OutputStream outStream, 212 @Nullable final OutputStream errStream, 213 @NotNull final String... args) 214 { 215 if ((args == null) || (args.length == 0) || 216 args[0].equalsIgnoreCase("version")) 217 { 218 if (outStream != null) 219 { 220 final PrintStream out = new PrintStream(outStream); 221 for (final String line : Version.getVersionLines()) 222 { 223 out.println(line); 224 } 225 } 226 227 return ResultCode.SUCCESS; 228 } 229 230 final String firstArg = StaticUtils.toLowerCase(args[0]); 231 final String[] remainingArgs = new String[args.length - 1]; 232 System.arraycopy(args, 1, remainingArgs, 0, remainingArgs.length); 233 234 if (firstArg.equals("authrate")) 235 { 236 return AuthRate.main(remainingArgs, outStream, errStream); 237 } 238 else if (firstArg.equals("base64")) 239 { 240 return Base64Tool.main(System.in, outStream, errStream, remainingArgs); 241 } 242 else if (firstArg.equals("collect-support-data")) 243 { 244 return CollectSupportData.main(outStream, errStream, remainingArgs); 245 } 246 else if (firstArg.equals("deliver-one-time-password")) 247 { 248 return DeliverOneTimePassword.main(remainingArgs, outStream, errStream); 249 } 250 else if (firstArg.equals("deliver-password-reset-token")) 251 { 252 return DeliverPasswordResetToken.main(remainingArgs, outStream, 253 errStream); 254 } 255 else if (firstArg.equals("dump-dns")) 256 { 257 return DumpDNs.main(remainingArgs, outStream, errStream); 258 } 259 else if (firstArg.equals("identify-references-to-missing-entries")) 260 { 261 return IdentifyReferencesToMissingEntries.main(remainingArgs, outStream, 262 errStream); 263 } 264 else if (firstArg.equals("identify-unique-attribute-conflicts")) 265 { 266 return IdentifyUniqueAttributeConflicts.main(remainingArgs, outStream, 267 errStream); 268 } 269 else if (firstArg.equals("in-memory-directory-server")) 270 { 271 return InMemoryDirectoryServerTool.main(remainingArgs, outStream, 272 errStream); 273 } 274 else if (firstArg.equals("indent-ldap-filter")) 275 { 276 return IndentLDAPFilter.main(outStream, errStream, remainingArgs); 277 } 278 else if (firstArg.equals("generate-schema-from-source")) 279 { 280 return GenerateSchemaFromSource.main(remainingArgs, outStream, errStream); 281 } 282 else if (firstArg.equals("generate-source-from-schema")) 283 { 284 return GenerateSourceFromSchema.main(remainingArgs, outStream, errStream); 285 } 286 else if (firstArg.equals("generate-totp-shared-secret")) 287 { 288 return GenerateTOTPSharedSecret.main(outStream, errStream, remainingArgs); 289 } 290 else if (firstArg.equals("ldapcompare")) 291 { 292 return LDAPCompare.main(outStream, errStream, remainingArgs); 293 } 294 else if (firstArg.equals("ldapdelete")) 295 { 296 return LDAPDelete.main(System.in, outStream, errStream, remainingArgs); 297 } 298 else if (firstArg.equals("ldapmodify")) 299 { 300 return LDAPModify.main(System.in, outStream, errStream, remainingArgs); 301 } 302 else if (firstArg.equals("ldappasswordmodify")) 303 { 304 return LDAPPasswordModify.main(outStream, errStream, remainingArgs); 305 } 306 else if (firstArg.equals("ldapsearch")) 307 { 308 return LDAPSearch.main(outStream, errStream, remainingArgs); 309 } 310 else if (firstArg.equals("ldap-debugger")) 311 { 312 return LDAPDebugger.main(remainingArgs, outStream, errStream); 313 } 314 else if (firstArg.equals("ldifmodify")) 315 { 316 return LDIFModify.main(outStream, errStream, remainingArgs); 317 } 318 else if (firstArg.equals("ldifsearch")) 319 { 320 return LDIFSearch.main(outStream, errStream, remainingArgs); 321 } 322 else if (firstArg.equals("ldif-diff")) 323 { 324 return LDIFDiff.main(outStream, errStream, remainingArgs); 325 } 326 else if (firstArg.equals("manage-account")) 327 { 328 return ManageAccount.main(outStream, errStream, remainingArgs); 329 } 330 else if (firstArg.equals("manage-certificates")) 331 { 332 return ManageCertificates.main(System.in, outStream, errStream, 333 remainingArgs); 334 } 335 else if (firstArg.equals("modrate")) 336 { 337 return ModRate.main(remainingArgs, outStream, errStream); 338 } 339 else if (firstArg.equals("move-subtree")) 340 { 341 return MoveSubtree.main(remainingArgs, outStream, errStream); 342 } 343 else if (firstArg.equals("register-yubikey-otp-device")) 344 { 345 return RegisterYubiKeyOTPDevice.main(remainingArgs, outStream, errStream); 346 } 347 else if (firstArg.equals("searchrate")) 348 { 349 return SearchRate.main(remainingArgs, outStream, errStream); 350 } 351 else if (firstArg.equals("search-and-mod-rate")) 352 { 353 return SearchAndModRate.main(remainingArgs, outStream, errStream); 354 } 355 else if (firstArg.equals("split-ldif")) 356 { 357 return SplitLDIF.main(outStream, errStream, remainingArgs); 358 } 359 else if (firstArg.equals("subtree-accessibility")) 360 { 361 return SubtreeAccessibility.main(remainingArgs, outStream, errStream); 362 } 363 else if (firstArg.equals("summarize-access-log")) 364 { 365 return SummarizeAccessLog.main(remainingArgs, outStream, errStream); 366 } 367 else if (firstArg.equals("test-ldap-sdk-performance")) 368 { 369 return TestLDAPSDKPerformance.main(outStream, errStream, remainingArgs); 370 } 371 else if (firstArg.equals("tls-cipher-suite-selector")) 372 { 373 return TLSCipherSuiteSelector.main(outStream, errStream, remainingArgs); 374 } 375 else if (firstArg.equals("transform-ldif")) 376 { 377 return TransformLDIF.main(outStream, errStream, remainingArgs); 378 } 379 else if (firstArg.equals("validate-ldap-schema")) 380 { 381 return ValidateLDAPSchema.main(outStream, errStream, remainingArgs); 382 } 383 else if (firstArg.equals("validate-ldif")) 384 { 385 return ValidateLDIF.main(remainingArgs, outStream, errStream); 386 } 387 else 388 { 389 if (errStream != null) 390 { 391 final PrintStream err = new PrintStream(errStream); 392 err.println("Unrecognized tool name '" + args[0] + '\''); 393 err.println("Supported tool names include:"); 394 err.println(" authrate"); 395 err.println(" base64"); 396 err.println(" collect-support-data"); 397 err.println(" deliver-one-time-password"); 398 err.println(" deliver-password-reset-token"); 399 err.println(" dump-dns"); 400 err.println(" generate-schema-from-source"); 401 err.println(" generate-source-from-schema"); 402 err.println(" generate-totp-shared-secret"); 403 err.println(" identify-references-to-missing-entries"); 404 err.println(" identify-unique-attribute-conflicts"); 405 err.println(" indent-ldap-filter"); 406 err.println(" in-memory-directory-server"); 407 err.println(" ldapcompare"); 408 err.println(" ldapdelete"); 409 err.println(" ldapmodify"); 410 err.println(" ldappasswordmodify"); 411 err.println(" ldapsearch"); 412 err.println(" ldap-debugger"); 413 err.println(" ldifmodify"); 414 err.println(" ldifsearch"); 415 err.println(" ldif-diff"); 416 err.println(" manage-account"); 417 err.println(" manage-certificates"); 418 err.println(" modrate"); 419 err.println(" move-subtree"); 420 err.println(" register-yubikey-otp-device"); 421 err.println(" searchrate"); 422 err.println(" search-and-mod-rate"); 423 err.println(" split-ldif"); 424 err.println(" subtree-accessibility"); 425 err.println(" summarize-access-log"); 426 err.println(" test-ldap-sdk-performance"); 427 err.println(" tls-cipher-suite-selector"); 428 err.println(" transform-ldif"); 429 err.println(" validate-ldap-schema"); 430 err.println(" validate-ldif"); 431 err.println(" version"); 432 } 433 434 return ResultCode.PARAM_ERROR; 435 } 436 } 437 438 439 440 /** 441 * Retrieves a list of all of the classes that provide the implementations for 442 * all of the command-line tools included with the LDAP SDK. 443 * 444 * @return A list of all of the classes that provide the implementations for 445 * all of the command-line tools included with the LDAP SDK. 446 */ 447 @NotNull() 448 public static List<Class<? extends CommandLineTool>> getToolClasses() 449 { 450 return Arrays.asList( 451 AuthRate.class, 452 Base64Tool.class, 453 CollectSupportData.class, 454 DeliverOneTimePassword.class, 455 DeliverPasswordResetToken.class, 456 DumpDNs.class, 457 GenerateSchemaFromSource.class, 458 GenerateSourceFromSchema.class, 459 GenerateTOTPSharedSecret.class, 460 IdentifyReferencesToMissingEntries.class, 461 IdentifyUniqueAttributeConflicts.class, 462 IndentLDAPFilter.class, 463 InMemoryDirectoryServerTool.class, 464 LDAPCompare.class, 465 LDAPDebugger.class, 466 LDAPDelete.class, 467 LDAPModify.class, 468 LDAPPasswordModify.class, 469 LDAPSearch.class, 470 LDIFDiff.class, 471 LDIFModify.class, 472 LDIFSearch.class, 473 ManageAccount.class, 474 ManageCertificates.class, 475 ModRate.class, 476 MoveSubtree.class, 477 RegisterYubiKeyOTPDevice.class, 478 SearchAndModRate.class, 479 SearchRate.class, 480 SplitLDIF.class, 481 SubtreeAccessibility.class, 482 SummarizeAccessLog.class, 483 TestLDAPSDKPerformance.class, 484 TLSCipherSuiteSelector.class, 485 TransformLDIF.class, 486 ValidateLDAPSchema.class, 487 ValidateLDIF.class); 488 } 489 490 491 492 /** 493 * Retrieves an instance of the specified type of command-line tool with the 494 * given output and error streams. The tool class must provide a two-argument 495 * constructor in which the first argument is a possibly-{@code null} 496 * {@code OutputStream} to use for standard output, and the second argument is 497 * a possibly-{@code null} {@code OutputStream} to use for standard error. 498 * 499 * @param toolClass The class that provides the implementation for the 500 * desired command-line tool. 501 * @param outStream The output stream to which standard out should be 502 * written. It may be {@code null} if output should be 503 * suppressed. 504 * @param errStream The output stream to which standard error should be 505 * written. It may be {@code null} if error messages 506 * should be suppressed. 507 * 508 * @return An instance of the specified command-line tool. 509 * 510 * @throws LDAPException If a problem occurs while attempting to create an 511 * instance of the requested tool. 512 */ 513 @NotNull() 514 public static CommandLineTool getToolInstance( 515 @NotNull final Class<?> toolClass, 516 @Nullable final OutputStream outStream, 517 @Nullable final OutputStream errStream) 518 throws LDAPException 519 { 520 if (! CommandLineTool.class.isAssignableFrom(toolClass)) 521 { 522 throw new LDAPException(ResultCode.PARAM_ERROR, 523 ERR_LAUNCHER_CLASS_NOT_COMMAND_LINE_TOOL.get(toolClass.getName(), 524 CommandLineTool.class.getName())); 525 } 526 527 final Constructor<?> constructor; 528 try 529 { 530 constructor = toolClass.getConstructor(OutputStream.class, 531 OutputStream.class); 532 } 533 catch (final Exception e) 534 { 535 Debug.debugException(e); 536 throw new LDAPException(ResultCode.PARAM_ERROR, 537 ERR_LAUNCHER_TOOL_CLASS_MISSING_EXPECTED_CONSTRUCTOR.get( 538 toolClass.getName()), 539 e); 540 } 541 542 543 try 544 { 545 return (CommandLineTool) constructor.newInstance(outStream, errStream); 546 } 547 catch (final Exception e) 548 { 549 Debug.debugException(e); 550 throw new LDAPException(ResultCode.LOCAL_ERROR, 551 ERR_LAUNCHER_ERROR_INVOKING_CONSTRUCTOR.get(toolClass.getName(), 552 StaticUtils.getExceptionMessage(e)), 553 e); 554 } 555 } 556}