All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.unboundid.ldap.sdk.unboundidds.tools.ManageAccountProcessor Maven / Gradle / Ivy

/*
 * Copyright 2016-2020 Ping Identity Corporation
 * All Rights Reserved.
 */
/*
 * Copyright 2016-2020 Ping Identity Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Copyright (C) 2016-2020 Ping Identity Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (GPLv2 only)
 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see .
 */
package com.unboundid.ldap.sdk.unboundidds.tools;



import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.ExtendedResult;
import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPConnectionPool;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.ldap.sdk.unboundidds.extensions.
            PasswordPolicyStateAccountUsabilityError;
import com.unboundid.ldap.sdk.unboundidds.extensions.
            PasswordPolicyStateAccountUsabilityNotice;
import com.unboundid.ldap.sdk.unboundidds.extensions.
            PasswordPolicyStateAccountUsabilityWarning;
import com.unboundid.ldap.sdk.unboundidds.extensions.
            PasswordPolicyStateExtendedRequest;
import com.unboundid.ldap.sdk.unboundidds.extensions.
            PasswordPolicyStateExtendedResult;
import com.unboundid.ldap.sdk.unboundidds.extensions.
            PasswordPolicyStateOperation;
import com.unboundid.ldif.LDIFWriter;
import com.unboundid.util.Debug;
import com.unboundid.util.FixedRateBarrier;
import com.unboundid.util.NotNull;
import com.unboundid.util.Nullable;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.args.ArgumentParser;
import com.unboundid.util.args.BooleanValueArgument;
import com.unboundid.util.args.StringArgument;
import com.unboundid.util.args.SubCommand;
import com.unboundid.util.args.TimestampArgument;

import static com.unboundid.ldap.sdk.unboundidds.tools.ToolMessages.*;



/**
 * This class provides a mechanism for ensuring that entries targeted by the
 * manage-account tool are processed properly, whether by the thread providing
 * the DN of the entry to update, or by a separate worker thread.
 * 
*
* NOTE: This class, and other classes within the * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only * supported for use against Ping Identity, UnboundID, and * Nokia/Alcatel-Lucent 8661 server products. These classes provide support * for proprietary functionality or for external specifications that are not * considered stable or mature enough to be guaranteed to work in an * interoperable way with other types of LDAP servers. *
*/ final class ManageAccountProcessor { // The argument parser for the manage-account tool. @NotNull private final ArgumentParser parser; // Indicates whether to suppress result operations without values. private final boolean suppressEmptyResultOperations; // The optional rate limiter that will be used when processing operations. @Nullable private final FixedRateBarrier rateLimiter; // The connection pool to use for all LDAP communication. @NotNull private final LDAPConnectionPool pool; // An LDIF writer that will be used to record information about all results. @NotNull private final LDIFWriter outputWriter; // An optional LDIF writer that will be used to record information about // failed operations. @Nullable private final LDIFWriter rejectWriter; // An optional queue used to hold the DNs of entries to process. @Nullable private final LinkedBlockingQueue dnQueue; // The list of processor threads that have been created. @NotNull private final List processorThreads; // A handle to the manage-account tool instance with which this processor is // associated. @NotNull private final ManageAccount manageAccount; // The password policy state operation to be processed. @NotNull private final PasswordPolicyStateOperation pwpStateOperation; // The string representation of the core manage-account command line (minus // connection, authentication, and target user arguments) being processed. @NotNull private final String commandLine; /** * Creates a new manage account processor with the provided information. * * @param manageAccount A handle to the manage-account tool instance with * which this processor is associated. * @param pool The connection pool to use for all LDAP * communication. * @param rateLimiter An optional rate limiter that will be used when * processing operations. * @param outputWriter The writer that will be used to write information * about all operations processed, whether successful * or not. * @param rejectWriter An optional LDIF writer that will be used to record * information about failed operations. * * @throws LDAPException If a problem is encountered while initializing this * account processor. */ ManageAccountProcessor(@NotNull final ManageAccount manageAccount, @NotNull final LDAPConnectionPool pool, @Nullable final FixedRateBarrier rateLimiter, @NotNull final LDIFWriter outputWriter, @Nullable final LDIFWriter rejectWriter) throws LDAPException { this.manageAccount = manageAccount; this.pool = pool; this.rateLimiter = rateLimiter; this.outputWriter = outputWriter; this.rejectWriter = rejectWriter; parser = manageAccount.getArgumentParser(); suppressEmptyResultOperations = parser.getBooleanArgument( ManageAccount.ARG_SUPPRESS_EMPTY_RESULT_OPERATIONS).isPresent(); // Create the password policy state operation that will be processed for // each matching entry. final StringBuilder commandBuffer = new StringBuilder(); pwpStateOperation = createPasswordPolicyStateOperation(commandBuffer); commandLine = commandBuffer.toString(); // Figure out how many threads to use to process manage-account operations. // If there should be more than one, then create a queue to hold the DNs // of the entries to process. final int numThreads = parser.getIntegerArgument(ManageAccount.ARG_NUM_THREADS).getValue(); if (numThreads > 1) { dnQueue = new LinkedBlockingQueue<>(100); processorThreads = new ArrayList<>(numThreads); for (int i=1; i <= numThreads; i++) { final ManageAccountProcessorThread processorThread = new ManageAccountProcessorThread(i, this); processorThread.start(); processorThreads.add(processorThread); } } else { dnQueue = null; processorThreads = Collections.emptyList(); } } /** * Ensures that the password policy state operation is processed for the entry * with the given DN. This will either process the operation immediately in * the current thread (if a single manage-account thread is configured), or * will enqueue the DN to be processed by another thread. * * @param dn The DN of the entry to process. */ void process(@NotNull final String dn) { if (dnQueue == null) { if (pwpStateOperation == null) { process(new PasswordPolicyStateExtendedRequest(dn)); } else { process(new PasswordPolicyStateExtendedRequest(dn, pwpStateOperation)); } } else { while (! manageAccount.cancelRequested()) { try { if (dnQueue.offer(dn, 100L, TimeUnit.MILLISECONDS)) { return; } } catch (final Exception e) { Debug.debugException(e); } } } } /** * Retrieves the next password policy state extended request to be processed. * This should only be called by {@link ManageAccountProcessorThread} * instances. * * @return The next password policy state extended request to be processed, * or {@code null} if no more processing should be performed. */ @Nullable() PasswordPolicyStateExtendedRequest getRequest() { // If the tool has been interrupted, then return null to signal that the // thread should exit. if (manageAccount.cancelRequested()) { return null; } // Get the DN of the next entry to process. Get it without waiting if we // can, but check for cancel and end of input regularly. String dn = dnQueue.poll(); while (dn == null) { if (manageAccount.cancelRequested()) { return null; } if (manageAccount.allDNsProvided()) { dn = dnQueue.poll(); if (dn == null) { return null; } else { break; } } try { dn = dnQueue.poll(100L, TimeUnit.MILLISECONDS); } catch (final Exception e) { Debug.debugException(e); if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } } } if (pwpStateOperation == null) { return new PasswordPolicyStateExtendedRequest(dn); } else { return new PasswordPolicyStateExtendedRequest(dn, pwpStateOperation); } } /** * Performs the appropriate processing for the provided password policy state * extended request. * * @param request The password policy state extended request to process. */ void process(@NotNull final PasswordPolicyStateExtendedRequest request) { // Get a connection to use to process the operation. LDAPConnection conn; try { conn = pool.getConnection(); } catch (final LDAPException le) { Debug.debugException(le); handleResult(request, le); return; } boolean alreadyReleased = false; boolean releaseAsDefunct = true; try { // If there is a rate limiter, then wait until it allows us to proceed. if (rateLimiter != null) { rateLimiter.await(); } // Try to process the operation. PasswordPolicyStateExtendedResult result; try { result = (PasswordPolicyStateExtendedResult) conn.processExtendedOperation(request); } catch (final LDAPException le) { Debug.debugException(le); try { result = new PasswordPolicyStateExtendedResult(new ExtendedResult(le)); } catch (final LDAPException le2) { Debug.debugException(le2); result = null; } } // If we have a non-null result with a result code that indicates that // the connection is still usable, then we're done and we can release // the connection for re-use. if ((result != null) && (result.getResultCode().isConnectionUsable())) { handleResult(request, result); releaseAsDefunct = false; return; } // If we've gotten here, then something went very wrong with the first // attempt. Try to replace the connection with a newly-created one. try { alreadyReleased = true; conn = pool.replaceDefunctConnection(conn); alreadyReleased = false; } catch (final LDAPException le) { Debug.debugException(le); // We couldn't replace the connection, so there's nothing else to try. handleResult(request, le); return; } // Make a second attempt at processing the operation. try { result = (PasswordPolicyStateExtendedResult) conn.processExtendedOperation(request); } catch (final LDAPException le) { Debug.debugException(le); try { result = new PasswordPolicyStateExtendedResult(new ExtendedResult(le)); } catch (final LDAPException le2) { Debug.debugException(le2); handleResult(request, le); return; } } if (result.getResultCode().isConnectionUsable()) { releaseAsDefunct = false; } handleResult(request, result); } finally { if (! alreadyReleased) { if (releaseAsDefunct) { pool.releaseDefunctConnection(conn); } else { pool.releaseConnection(conn); } } } } /** * Performs the appropriate processing for a result that failed with an * {@code LDAPException}. * * @param request The request that was processed. * @param le The exception caught during processing. */ private void handleResult( @NotNull final PasswordPolicyStateExtendedRequest request, @NotNull final LDAPException le) { try { final PasswordPolicyStateExtendedResult result = new PasswordPolicyStateExtendedResult(new ExtendedResult(le)); handleResult(request, result); return; } catch (final Exception e) { Debug.debugException(e); } handleResult(createResultEntry(request, le.toLDAPResult()), true); } /** * Performs the appropriate processing for the provided result. * * @param request The request that was processed. * @param result The result of the processing. */ private void handleResult( @NotNull final PasswordPolicyStateExtendedRequest request, @NotNull final PasswordPolicyStateExtendedResult result) { handleResult(createResultEntry(request, result), (result.getResultCode() != ResultCode.SUCCESS)); } /** * Ensures that the provided message (e.g., information about an error * encountered from something other than a password policy state operation) is * written to the output writer and optionally the reject writer. The message * will be written as an LDIF comment. * * @param message The message to be written. It must not be {@code null}. * @param isFailure Indicates whether the message should also be written to * the reject writer if one is defined. */ void handleMessage(@NotNull final String message, final boolean isFailure) { synchronized (outputWriter) { try { outputWriter.writeComment(message, true, true); outputWriter.flush(); } catch (final Exception e) { // We can't really do anything about this. Debug.debugException(e); } } if (isFailure && (rejectWriter != null)) { synchronized (rejectWriter) { try { rejectWriter.writeComment(message, true, true); rejectWriter.flush(); } catch (final Exception e) { // We can't really do anything about this. Debug.debugException(e); } } } } /** * Creates an entry that encapsulates the content of the provided result. * * @param request The request that was processed. * @param result The result of the processing. * * @return The entry that was created. */ @NotNull() private Entry createResultEntry( @NotNull final PasswordPolicyStateExtendedRequest request, @NotNull final LDAPResult result) { final Entry e = new Entry(request.getUserDN()); e.addAttribute("base-command-line", commandLine + " --targetDN " + StaticUtils.cleanExampleCommandLineArgument(e.getDN())); e.addAttribute("result-code", String.valueOf(result.getResultCode().intValue())); final String resultCodeName = result.getResultCode().getName(); if (resultCodeName != null) { e.addAttribute("result-code-name", resultCodeName); } final String diagnosticMessage = result.getDiagnosticMessage(); if (diagnosticMessage != null) { e.addAttribute("diagnostic-message", diagnosticMessage); } final String matchedDN = result.getMatchedDN(); if (matchedDN != null) { e.addAttribute("matched-dn", matchedDN); } final String[] referralURLs = result.getReferralURLs(); if ((referralURLs != null) && (referralURLs.length > 0)) { e.addAttribute("referral-url", referralURLs); } if (! (result instanceof PasswordPolicyStateExtendedResult)) { return e; } final PasswordPolicyStateExtendedResult r = (PasswordPolicyStateExtendedResult) result; for (final PasswordPolicyStateOperation o : r.getOperations()) { final String[] values = o.getStringValues(); if (values.length == 0) { if (suppressEmptyResultOperations) { continue; } } final String attrName; final ManageAccountSubCommandType subcommandType = ManageAccountSubCommandType.forOperationType(o.getOperationType()); if (subcommandType == null) { if (o.getOperationType() == 39) { // This is a deprecated response that the client doesn't support, but // older servers may return it. attrName = "get-password-history"; } else { // This result may come from a newer version of the server that has // additional password policy state operation types. attrName = "unrecognized-operation-type-" + o.getOperationType(); } } else { attrName = subcommandType.getPrimaryName(); } if (values.length == 0) { e.addAttribute(attrName, ""); } else { // There may be some subcommands that require special treatment. Handle // those specially. Otherwise, just go with the string representations. switch (subcommandType) { case GET_ACCOUNT_USABILITY_NOTICES: final String[] notices = new String[values.length]; for (int i=0; i < values.length; i++) { try { notices[i] = new PasswordPolicyStateAccountUsabilityNotice( values[i]).getMessage(); } catch (final Exception ex) { Debug.debugException(ex); notices[i] = values[i]; } } e.addAttribute(attrName, notices); break; case GET_ACCOUNT_USABILITY_WARNINGS: final String[] warnings = new String[values.length]; for (int i=0; i < values.length; i++) { try { warnings[i] = new PasswordPolicyStateAccountUsabilityWarning( values[i]).getMessage(); } catch (final Exception ex) { Debug.debugException(ex); warnings[i] = values[i]; } } e.addAttribute(attrName, warnings); break; case GET_ACCOUNT_USABILITY_ERRORS: final String[] errors = new String[values.length]; for (int i=0; i < values.length; i++) { try { errors[i] = new PasswordPolicyStateAccountUsabilityError( values[i]).getMessage(); } catch (final Exception ex) { Debug.debugException(ex); errors[i] = values[i]; } } e.addAttribute(attrName, errors); break; default: e.addAttribute(attrName, values); break; } } } return e; } /** * Ensures that the provided entry is output to either the tool's output or * error stream, and also to the reject writer if appropriate. * * @param resultEntry The entry to be written. * @param isFailure Indicates whether the operation was considered a * failure and should be recorded in the reject writer. */ private void handleResult(@NotNull final Entry resultEntry, final boolean isFailure) { synchronized (outputWriter) { try { outputWriter.writeEntry(resultEntry); outputWriter.flush(); } catch (final Exception e) { // We can't really do anything about this. Debug.debugException(e); } } if (isFailure && (rejectWriter != null)) { synchronized (rejectWriter) { try { rejectWriter.writeEntry(resultEntry); rejectWriter.flush(); } catch (final Exception e) { // We can't really do anything about this. Debug.debugException(e); } } } } /** * Creates the password policy state operation that will be processed against * all target entries. * * @param commandBuffer The buffer to which the manage-account command line * should be appended. * * @return The password policy state operation that was created. * * @throws LDAPException If a problem is encountered while creating the * password policy state operation. */ @NotNull() private PasswordPolicyStateOperation createPasswordPolicyStateOperation( @NotNull final StringBuilder commandBuffer) throws LDAPException { final SubCommand subcommand = parser.getSelectedSubCommand(); if (subcommand == null) { // This should never happen. throw new LDAPException(ResultCode.PARAM_ERROR, ERR_MANAGE_ACCT_PROCESSOR_NO_SUBCOMMAND.get( manageAccount.getToolName())); } final ManageAccountSubCommandType subcommandType = ManageAccountSubCommandType.forName(subcommand.getPrimaryName()); if (subcommandType == null) { // This should also never happen. throw new LDAPException(ResultCode.LOCAL_ERROR, ERR_MANAGE_ACCT_PROCESSOR_UNSUPPORTED_SUBCOMMAND.get( subcommand.getPrimaryName(), manageAccount.getToolName())); } commandBuffer.append(manageAccount.getToolName()); commandBuffer.append(' '); commandBuffer.append(subcommandType.getPrimaryName()); switch (subcommandType) { case GET_ALL: // The get-all operation is invoked by sending a password policy state // extended request without any operations. return null; case GET_PASSWORD_POLICY_DN: return PasswordPolicyStateOperation. createGetPasswordPolicyDNOperation(); case GET_ACCOUNT_IS_USABLE: return PasswordPolicyStateOperation.createGetAccountIsUsableOperation(); case GET_ACCOUNT_USABILITY_NOTICES: return PasswordPolicyStateOperation. createGetAccountUsabilityNoticesOperation(); case GET_ACCOUNT_USABILITY_WARNINGS: return PasswordPolicyStateOperation. createGetAccountUsabilityWarningsOperation(); case GET_ACCOUNT_USABILITY_ERRORS: return PasswordPolicyStateOperation. createGetAccountUsabilityErrorsOperation(); case GET_PASSWORD_CHANGED_TIME: return PasswordPolicyStateOperation. createGetPasswordChangedTimeOperation(); case SET_PASSWORD_CHANGED_TIME: return PasswordPolicyStateOperation. createSetPasswordChangedTimeOperation( getDate(subcommand, commandBuffer)); case CLEAR_PASSWORD_CHANGED_TIME: return PasswordPolicyStateOperation. createClearPasswordChangedTimeOperation(); case GET_ACCOUNT_IS_DISABLED: return PasswordPolicyStateOperation. createGetAccountDisabledStateOperation(); case SET_ACCOUNT_IS_DISABLED: return PasswordPolicyStateOperation. createSetAccountDisabledStateOperation( getBoolean(subcommand, commandBuffer)); case CLEAR_ACCOUNT_IS_DISABLED: return PasswordPolicyStateOperation. createClearAccountDisabledStateOperation(); case GET_ACCOUNT_ACTIVATION_TIME: return PasswordPolicyStateOperation. createGetAccountActivationTimeOperation(); case SET_ACCOUNT_ACTIVATION_TIME: return PasswordPolicyStateOperation. createSetAccountActivationTimeOperation( getDate(subcommand, commandBuffer)); case CLEAR_ACCOUNT_ACTIVATION_TIME: return PasswordPolicyStateOperation. createClearAccountActivationTimeOperation(); case GET_SECONDS_UNTIL_ACCOUNT_ACTIVATION: return PasswordPolicyStateOperation. createGetSecondsUntilAccountActivationOperation(); case GET_ACCOUNT_IS_NOT_YET_ACTIVE: return PasswordPolicyStateOperation. createGetAccountIsNotYetActiveOperation(); case GET_ACCOUNT_EXPIRATION_TIME: return PasswordPolicyStateOperation. createGetAccountExpirationTimeOperation(); case SET_ACCOUNT_EXPIRATION_TIME: return PasswordPolicyStateOperation. createSetAccountExpirationTimeOperation( getDate(subcommand, commandBuffer)); case CLEAR_ACCOUNT_EXPIRATION_TIME: return PasswordPolicyStateOperation. createClearAccountExpirationTimeOperation(); case GET_SECONDS_UNTIL_ACCOUNT_EXPIRATION: return PasswordPolicyStateOperation. createGetSecondsUntilAccountExpirationOperation(); case GET_ACCOUNT_IS_EXPIRED: return PasswordPolicyStateOperation. createGetAccountIsExpiredOperation(); case GET_PASSWORD_EXPIRATION_WARNED_TIME: return PasswordPolicyStateOperation. createGetPasswordExpirationWarnedTimeOperation(); case SET_PASSWORD_EXPIRATION_WARNED_TIME: return PasswordPolicyStateOperation. createSetPasswordExpirationWarnedTimeOperation( getDate(subcommand, commandBuffer)); case CLEAR_PASSWORD_EXPIRATION_WARNED_TIME: return PasswordPolicyStateOperation. createClearPasswordExpirationWarnedTimeOperation(); case GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING: return PasswordPolicyStateOperation. createGetSecondsUntilPasswordExpirationWarningOperation(); case GET_PASSWORD_EXPIRATION_TIME: return PasswordPolicyStateOperation. createGetPasswordExpirationTimeOperation(); case GET_SECONDS_UNTIL_PASSWORD_EXPIRATION: return PasswordPolicyStateOperation. createGetSecondsUntilPasswordExpirationOperation(); case GET_PASSWORD_IS_EXPIRED: return PasswordPolicyStateOperation. createGetPasswordIsExpiredOperation(); case GET_ACCOUNT_IS_FAILURE_LOCKED: return PasswordPolicyStateOperation. createGetAccountIsFailureLockedOperation(); case SET_ACCOUNT_IS_FAILURE_LOCKED: return PasswordPolicyStateOperation. createSetAccountIsFailureLockedOperation( getBoolean(subcommand, commandBuffer)); case GET_FAILURE_LOCKOUT_TIME: return PasswordPolicyStateOperation. createGetFailureLockoutTimeOperation(); case GET_SECONDS_UNTIL_AUTHENTICATION_FAILURE_UNLOCK: return PasswordPolicyStateOperation. createGetSecondsUntilAuthenticationFailureUnlockOperation(); case GET_AUTHENTICATION_FAILURE_TIMES: return PasswordPolicyStateOperation. createGetAuthenticationFailureTimesOperation(); case ADD_AUTHENTICATION_FAILURE_TIME: return PasswordPolicyStateOperation. createAddAuthenticationFailureTimeOperation( getDates(subcommand, commandBuffer)); case SET_AUTHENTICATION_FAILURE_TIMES: return PasswordPolicyStateOperation. createSetAuthenticationFailureTimesOperation( getDates(subcommand, commandBuffer)); case CLEAR_AUTHENTICATION_FAILURE_TIMES: return PasswordPolicyStateOperation. createClearAuthenticationFailureTimesOperation(); case GET_REMAINING_AUTHENTICATION_FAILURE_COUNT: return PasswordPolicyStateOperation. createGetRemainingAuthenticationFailureCountOperation(); case GET_ACCOUNT_IS_IDLE_LOCKED: return PasswordPolicyStateOperation. createGetAccountIsIdleLockedOperation(); case GET_SECONDS_UNTIL_IDLE_LOCKOUT: return PasswordPolicyStateOperation. createGetSecondsUntilIdleLockoutOperation(); case GET_IDLE_LOCKOUT_TIME: return PasswordPolicyStateOperation.createGetIdleLockoutTimeOperation(); case GET_MUST_CHANGE_PASSWORD: return PasswordPolicyStateOperation. createGetPasswordResetStateOperation(); case SET_MUST_CHANGE_PASSWORD: return PasswordPolicyStateOperation. createSetPasswordResetStateOperation( getBoolean(subcommand, commandBuffer)); case CLEAR_MUST_CHANGE_PASSWORD: return PasswordPolicyStateOperation. createClearPasswordResetStateOperation(); case GET_ACCOUNT_IS_PASSWORD_RESET_LOCKED: return PasswordPolicyStateOperation. createGetAccountIsResetLockedOperation(); case GET_SECONDS_UNTIL_PASSWORD_RESET_LOCKOUT: return PasswordPolicyStateOperation. createGetSecondsUntilPasswordResetLockoutOperation(); case GET_PASSWORD_RESET_LOCKOUT_TIME: return PasswordPolicyStateOperation. createGetResetLockoutTimeOperation(); case GET_LAST_LOGIN_TIME: return PasswordPolicyStateOperation.createGetLastLoginTimeOperation(); case SET_LAST_LOGIN_TIME: return PasswordPolicyStateOperation.createSetLastLoginTimeOperation( getDate(subcommand, commandBuffer)); case CLEAR_LAST_LOGIN_TIME: return PasswordPolicyStateOperation.createClearLastLoginTimeOperation(); case GET_LAST_LOGIN_IP_ADDRESS: return PasswordPolicyStateOperation. createGetLastLoginIPAddressOperation(); case SET_LAST_LOGIN_IP_ADDRESS: return PasswordPolicyStateOperation. createSetLastLoginIPAddressOperation( getString(subcommand, commandBuffer)); case CLEAR_LAST_LOGIN_IP_ADDRESS: return PasswordPolicyStateOperation. createClearLastLoginIPAddressOperation(); case GET_GRACE_LOGIN_USE_TIMES: return PasswordPolicyStateOperation. createGetGraceLoginUseTimesOperation(); case ADD_GRACE_LOGIN_USE_TIME: return PasswordPolicyStateOperation.createAddGraceLoginUseTimeOperation( getDates(subcommand, commandBuffer)); case SET_GRACE_LOGIN_USE_TIMES: return PasswordPolicyStateOperation. createSetGraceLoginUseTimesOperation( getDates(subcommand, commandBuffer)); case CLEAR_GRACE_LOGIN_USE_TIMES: return PasswordPolicyStateOperation. createClearGraceLoginUseTimesOperation(); case GET_REMAINING_GRACE_LOGIN_COUNT: return PasswordPolicyStateOperation. createGetRemainingGraceLoginCountOperation(); case GET_PASSWORD_CHANGED_BY_REQUIRED_TIME: return PasswordPolicyStateOperation. createGetPasswordChangedByRequiredTimeOperation(); case SET_PASSWORD_CHANGED_BY_REQUIRED_TIME: return PasswordPolicyStateOperation. createSetPasswordChangedByRequiredTimeOperation( getDate(subcommand, commandBuffer)); case CLEAR_PASSWORD_CHANGED_BY_REQUIRED_TIME: return PasswordPolicyStateOperation. createClearPasswordChangedByRequiredTimeOperation(); case GET_SECONDS_UNTIL_REQUIRED_PASSWORD_CHANGE_TIME: return PasswordPolicyStateOperation. createGetSecondsUntilRequiredChangeTimeOperation(); case GET_PASSWORD_HISTORY_COUNT: return PasswordPolicyStateOperation. createGetPasswordHistoryCountOperation(); case CLEAR_PASSWORD_HISTORY: return PasswordPolicyStateOperation. createClearPasswordHistoryOperation(); case GET_HAS_RETIRED_PASSWORD: return PasswordPolicyStateOperation.createHasRetiredPasswordOperation(); case GET_PASSWORD_RETIRED_TIME: return PasswordPolicyStateOperation. createGetPasswordRetiredTimeOperation(); case GET_RETIRED_PASSWORD_EXPIRATION_TIME: return PasswordPolicyStateOperation. createGetRetiredPasswordExpirationTimeOperation(); case CLEAR_RETIRED_PASSWORD: return PasswordPolicyStateOperation. createPurgeRetiredPasswordOperation(); case GET_AVAILABLE_SASL_MECHANISMS: return PasswordPolicyStateOperation. createGetAvailableSASLMechanismsOperation(); case GET_AVAILABLE_OTP_DELIVERY_MECHANISMS: return PasswordPolicyStateOperation. createGetAvailableOTPDeliveryMechanismsOperation(); case GET_HAS_TOTP_SHARED_SECRET: return PasswordPolicyStateOperation. createHasTOTPSharedSecretOperation(); case ADD_TOTP_SHARED_SECRET: return PasswordPolicyStateOperation.createAddTOTPSharedSecretOperation( getStrings(subcommand, commandBuffer)); case REMOVE_TOTP_SHARED_SECRET: return PasswordPolicyStateOperation. createRemoveTOTPSharedSecretOperation( getStrings(subcommand, commandBuffer)); case SET_TOTP_SHARED_SECRETS: return PasswordPolicyStateOperation.createSetTOTPSharedSecretsOperation( getStrings(subcommand, commandBuffer)); case CLEAR_TOTP_SHARED_SECRETS: return PasswordPolicyStateOperation. createClearTOTPSharedSecretsOperation(); case GET_HAS_REGISTERED_YUBIKEY_PUBLIC_ID: return PasswordPolicyStateOperation.createHasYubiKeyPublicIDOperation(); case GET_REGISTERED_YUBIKEY_PUBLIC_IDS: return PasswordPolicyStateOperation. createGetRegisteredYubiKeyPublicIDsOperation(); case ADD_REGISTERED_YUBIKEY_PUBLIC_ID: return PasswordPolicyStateOperation. createAddRegisteredYubiKeyPublicIDOperation( getStrings(subcommand, commandBuffer)); case REMOVE_REGISTERED_YUBIKEY_PUBLIC_ID: return PasswordPolicyStateOperation. createRemoveRegisteredYubiKeyPublicIDOperation( getStrings(subcommand, commandBuffer)); case SET_REGISTERED_YUBIKEY_PUBLIC_IDS: return PasswordPolicyStateOperation. createSetRegisteredYubiKeyPublicIDsOperation( getStrings(subcommand, commandBuffer)); case CLEAR_REGISTERED_YUBIKEY_PUBLIC_IDS: return PasswordPolicyStateOperation. createClearRegisteredYubiKeyPublicIDsOperation(); case GET_HAS_STATIC_PASSWORD: return PasswordPolicyStateOperation.createHasStaticPasswordOperation(); case GET_LAST_BIND_PASSWORD_VALIDATION_TIME: return PasswordPolicyStateOperation. createGetLastBindPasswordValidationTimeOperation(); case GET_SECONDS_SINCE_LAST_BIND_PASSWORD_VALIDATION: return PasswordPolicyStateOperation. createGetSecondsSinceLastBindPasswordValidationOperation(); case SET_LAST_BIND_PASSWORD_VALIDATION_TIME: return PasswordPolicyStateOperation. createSetLastBindPasswordValidationTimeOperation( getDate(subcommand, commandBuffer)); case CLEAR_LAST_BIND_PASSWORD_VALIDATION_TIME: return PasswordPolicyStateOperation. createClearLastBindPasswordValidationTimeOperation(); case GET_ACCOUNT_IS_VALIDATION_LOCKED: return PasswordPolicyStateOperation. createGetAccountIsValidationLockedOperation(); case SET_ACCOUNT_IS_VALIDATION_LOCKED: return PasswordPolicyStateOperation. createSetAccountIsValidationLockedOperation( getBoolean(subcommand, commandBuffer)); case GET_RECENT_LOGIN_HISTORY: return PasswordPolicyStateOperation. createGetRecentLoginHistoryOperation(); case CLEAR_RECENT_LOGIN_HISTORY: return PasswordPolicyStateOperation. createClearRecentLoginHistoryOperation(); default: // This should never happen. throw new LDAPException(ResultCode.LOCAL_ERROR, ERR_MANAGE_ACCT_PROCESSOR_UNSUPPORTED_SUBCOMMAND.get( subcommand.getPrimaryName(), manageAccount.getToolName())); } } /** * Retrieves the value of the "operationValue" argument from the provided * subcommand's argument parser as a {@code Date}. * * @param subcommand The subcommand to examine. * @param commandBuffer The buffer to which the manage-account command line * should be appended. * * @return The value of the "operationValue" argument. */ private static boolean getBoolean(@NotNull final SubCommand subcommand, @NotNull final StringBuilder commandBuffer) { final ArgumentParser parser = subcommand.getArgumentParser(); final BooleanValueArgument arg = parser.getBooleanValueArgument("operationValue"); final boolean booleanValue = arg.getValue(); if (arg.isPresent()) { commandBuffer.append(' '); commandBuffer.append(arg.getIdentifierString()); commandBuffer.append(' '); commandBuffer.append(booleanValue); } return booleanValue; } /** * Retrieves the value of the "operationValue" argument from the provided * subcommand's argument parser as a {@code Date}. * * @param subcommand The subcommand to examine. * @param commandBuffer The buffer to which the manage-account command line * should be appended. * * @return The value of the "operationValue" argument. */ @NotNull() private static Date getDate(@NotNull final SubCommand subcommand, @NotNull final StringBuilder commandBuffer) { final ArgumentParser parser = subcommand.getArgumentParser(); final TimestampArgument arg = parser.getTimestampArgument("operationValue"); final Date dateValue = arg.getValue(); if (arg.isPresent()) { commandBuffer.append(' '); commandBuffer.append(arg.getIdentifierString()); commandBuffer.append(' '); commandBuffer.append(StaticUtils.encodeGeneralizedTime(dateValue)); } return dateValue; } /** * Retrieves the value of the "operationValue" argument from the provided * subcommand's argument parser as an array of {@code Date} objects. * * @param subcommand The subcommand to examine. * @param commandBuffer The buffer to which the manage-account command line * should be appended. * * @return The value of the "operationValue" argument. */ @NotNull() private static Date[] getDates(@NotNull final SubCommand subcommand, @NotNull final StringBuilder commandBuffer) { final ArgumentParser parser = subcommand.getArgumentParser(); final TimestampArgument arg = parser.getTimestampArgument("operationValue"); final List dateList = arg.getValues(); final Date[] dateArray = new Date[dateList.size()]; dateList.toArray(dateArray); if (arg.isPresent()) { for (final Date d : dateArray) { commandBuffer.append(' '); commandBuffer.append(arg.getIdentifierString()); commandBuffer.append(' '); commandBuffer.append(StaticUtils.encodeGeneralizedTime(d)); } } return dateArray; } /** * Retrieves the value of the "operationValue" argument from the provided * subcommand's argument parser as a {@code String}. * * @param subcommand The subcommand to examine. * @param commandBuffer The buffer to which the manage-account command line * should be appended. * * @return The value of the "operationValue" argument. */ @NotNull() private static String getString(@NotNull final SubCommand subcommand, @NotNull final StringBuilder commandBuffer) { final ArgumentParser parser = subcommand.getArgumentParser(); final StringArgument arg = parser.getStringArgument("operationValue"); final String stringValue = arg.getValue(); if (arg.isPresent()) { commandBuffer.append(' '); commandBuffer.append(arg.getIdentifierString()); commandBuffer.append(' '); commandBuffer.append( StaticUtils.cleanExampleCommandLineArgument(stringValue)); } return stringValue; } /** * Retrieves the value of the "operationValue" argument from the provided * subcommand's argument parser as an array of {@code String} objects. * * @param subcommand The subcommand to examine. * @param commandBuffer The buffer to which the manage-account command line * should be appended. * * @return The value of the "operationValue" argument. */ @NotNull() private static String[] getStrings(@NotNull final SubCommand subcommand, @NotNull final StringBuilder commandBuffer) { final ArgumentParser parser = subcommand.getArgumentParser(); final StringArgument arg = parser.getStringArgument("operationValue"); final List stringList = arg.getValues(); final String[] stringArray = new String[stringList.size()]; stringList.toArray(stringArray); if (arg.isPresent()) { for (final String s : stringArray) { commandBuffer.append(' '); commandBuffer.append(arg.getIdentifierString()); commandBuffer.append(' '); commandBuffer.append(StaticUtils.cleanExampleCommandLineArgument(s)); } } return stringArray; } /** * Blocks until all entries have been processed. */ void waitForCompletion() { // If we don't have a DN queue, then all of the operations are processed // synchronously and we know that we're done. if (dnQueue == null) { return; } while (true) { // If the manage-account tool has been interrupted, then we can declare // the processing complete. We don't care about what's in the queue or // what the processor threads are doing. if (manageAccount.cancelRequested()) { return; } // If all of the DNs have been provided, then we still need to wait until // the queue is empty and all of the processor threads have completed. if (manageAccount.allDNsProvided() && (dnQueue.peek() == null)) { for (final ManageAccountProcessorThread t : processorThreads) { try { t.join(); } catch (final Exception e) { Debug.debugException(e); if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } } } return; } try { Thread.sleep(10L); } catch (final Exception e) { Debug.debugException(e); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy