001 /* 002 * Copyright 2008-2015 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2015 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021 package com.unboundid.ldap.sdk.unboundidds.extensions; 022 023 024 025 import com.unboundid.asn1.ASN1Element; 026 import com.unboundid.asn1.ASN1OctetString; 027 import com.unboundid.asn1.ASN1Sequence; 028 import com.unboundid.ldap.sdk.Control; 029 import com.unboundid.ldap.sdk.ExtendedRequest; 030 import com.unboundid.ldap.sdk.ExtendedResult; 031 import com.unboundid.ldap.sdk.LDAPConnection; 032 import com.unboundid.ldap.sdk.LDAPException; 033 import com.unboundid.ldap.sdk.ResultCode; 034 import com.unboundid.util.NotMutable; 035 import com.unboundid.util.ThreadSafety; 036 import com.unboundid.util.ThreadSafetyLevel; 037 038 import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 039 import static com.unboundid.util.Debug.*; 040 041 042 043 /** 044 * <BLOCKQUOTE> 045 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID 046 * LDAP SDK for Java. It is not available for use in applications that 047 * include only the Standard Edition of the LDAP SDK, and is not supported for 048 * use in conjunction with non-UnboundID products. 049 * </BLOCKQUOTE> 050 * This class provides an implementation of the password policy state extended 051 * request as used in the UnboundID Directory Server. It may be used to 052 * retrieve and/or alter password policy properties for a user account. See the 053 * documentation in the {@link PasswordPolicyStateOperation} class for 054 * information about the types of operations that can be performed. 055 * <BR><BR> 056 * <H2>Example</H2> 057 * The following example demonstrates the use of the password policy state 058 * extended operation to administratively disable a user's account: 059 * <PRE> 060 * PasswordPolicyStateOperation disableOp = 061 * PasswordPolicyStateOperation.createSetAccountDisabledStateOperation( 062 * true); 063 * PasswordPolicyStateExtendedRequest pwpStateRequest = 064 * new PasswordPolicyStateExtendedRequest( 065 * "uid=john.doe,ou=People,dc=example,dc=com", disableOp); 066 * PasswordPolicyStateExtendedResult pwpStateResult = 067 * (PasswordPolicyStateExtendedResult) 068 * connection.processExtendedOperation(pwpStateRequest); 069 * 070 * // NOTE: The processExtendedOperation method will generally only throw an 071 * // exception if a problem occurs while trying to send the request or read 072 * // the response. It will not throw an exception because of a non-success 073 * // response. 074 * 075 * if (pwpStateResult.getResultCode() == ResultCode.SUCCESS) 076 * { 077 * boolean isDisabled = pwpStateResult.getBooleanValue( 078 * PasswordPolicyStateOperation.OP_TYPE_GET_ACCOUNT_DISABLED_STATE); 079 * if (isDisabled) 080 * { 081 * // The user account has been disabled. 082 * } 083 * else 084 * { 085 * // The user account is not disabled. 086 * } 087 * } 088 * </PRE> 089 */ 090 @NotMutable() 091 @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 092 public final class PasswordPolicyStateExtendedRequest 093 extends ExtendedRequest 094 { 095 /** 096 * The OID (1.3.6.1.4.1.30221.1.6.1) for the password policy state extended 097 * request. 098 */ 099 public static final String PASSWORD_POLICY_STATE_REQUEST_OID = 100 "1.3.6.1.4.1.30221.1.6.1"; 101 102 103 104 /** 105 * The serial version UID for this serializable class. 106 */ 107 private static final long serialVersionUID = -1644137695182620213L; 108 109 110 111 // The set of password policy state operations to process. 112 private final PasswordPolicyStateOperation[] operations; 113 114 // The DN of the user account on which to operate. 115 private final String userDN; 116 117 118 119 /** 120 * Creates a new password policy state extended request with the provided user 121 * DN and optional set of operations. 122 * 123 * @param userDN The DN of the user account on which to operate. 124 * @param operations The set of password policy state operations to process. 125 * If no operations are provided, then the effect will be 126 * to retrieve the values of all available password policy 127 * state properties. 128 */ 129 public PasswordPolicyStateExtendedRequest(final String userDN, 130 final PasswordPolicyStateOperation... operations) 131 { 132 this(userDN, null, operations); 133 } 134 135 136 137 /** 138 * Creates a new password policy state extended request with the provided user 139 * DN, optional set of operations, and optional set of controls. 140 * 141 * @param userDN The DN of the user account on which to operate. 142 * @param controls The set of controls to include in the request. 143 * @param operations The set of password policy state operations to process. 144 * If no operations are provided, then the effect will be 145 * to retrieve the values of all available password policy 146 * state properties. 147 */ 148 public PasswordPolicyStateExtendedRequest(final String userDN, 149 final Control[] controls, 150 final PasswordPolicyStateOperation... operations) 151 { 152 super(PASSWORD_POLICY_STATE_REQUEST_OID, encodeValue(userDN, operations), 153 controls); 154 155 this.userDN = userDN; 156 this.operations = operations; 157 } 158 159 160 161 /** 162 * Creates a new password policy state extended request from the provided 163 * generic extended request. 164 * 165 * @param extendedRequest The generic extended request to use to create this 166 * password policy state extended request. 167 * 168 * @throws LDAPException If a problem occurs while decoding the request. 169 */ 170 public PasswordPolicyStateExtendedRequest( 171 final ExtendedRequest extendedRequest) 172 throws LDAPException 173 { 174 super(extendedRequest); 175 176 final ASN1OctetString value = extendedRequest.getValue(); 177 if (value == null) 178 { 179 throw new LDAPException(ResultCode.DECODING_ERROR, 180 ERR_PWP_STATE_REQUEST_NO_VALUE.get()); 181 } 182 183 final ASN1Element[] elements; 184 try 185 { 186 final ASN1Element valueElement = ASN1Element.decode(value.getValue()); 187 elements = ASN1Sequence.decodeAsSequence(valueElement).elements(); 188 } 189 catch (Exception e) 190 { 191 debugException(e); 192 throw new LDAPException(ResultCode.DECODING_ERROR, 193 ERR_PWP_STATE_REQUEST_VALUE_NOT_SEQUENCE.get(e), 194 e); 195 } 196 197 if ((elements.length < 1) || (elements.length > 2)) 198 { 199 throw new LDAPException(ResultCode.DECODING_ERROR, 200 ERR_PWP_STATE_REQUEST_INVALID_ELEMENT_COUNT.get( 201 elements.length)); 202 } 203 204 userDN = ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 205 206 if (elements.length == 1) 207 { 208 operations = new PasswordPolicyStateOperation[0]; 209 } 210 else 211 { 212 try 213 { 214 final ASN1Element[] opElements = 215 ASN1Sequence.decodeAsSequence(elements[1]).elements(); 216 operations = new PasswordPolicyStateOperation[opElements.length]; 217 for (int i=0; i < opElements.length; i++) 218 { 219 operations[i] = PasswordPolicyStateOperation.decode(opElements[i]); 220 } 221 } 222 catch (Exception e) 223 { 224 debugException(e); 225 throw new LDAPException(ResultCode.DECODING_ERROR, 226 ERR_PWP_STATE_REQUEST_CANNOT_DECODE_OPS.get(e), 227 e); 228 } 229 } 230 } 231 232 233 234 /** 235 * Encodes the provided information into an ASN.1 octet string that may be 236 * used as the value for this extended request. 237 * 238 * @param userDN The DN of the user account on which to operate. 239 * @param operations The set of operations to be processed. 240 * 241 * @return An ASN.1 octet string containing the encoded value. 242 */ 243 private static ASN1OctetString encodeValue(final String userDN, 244 final PasswordPolicyStateOperation[] operations) 245 { 246 final ASN1Element[] elements; 247 if ((operations == null) || (operations.length == 0)) 248 { 249 elements = new ASN1Element[] 250 { 251 new ASN1OctetString(userDN) 252 }; 253 } 254 else 255 { 256 final ASN1Element[] opElements = new ASN1Element[operations.length]; 257 for (int i=0; i < operations.length; i++) 258 { 259 opElements[i] = operations[i].encode(); 260 } 261 262 elements = new ASN1Element[] 263 { 264 new ASN1OctetString(userDN), 265 new ASN1Sequence(opElements) 266 }; 267 } 268 269 return new ASN1OctetString(new ASN1Sequence(elements).encode()); 270 } 271 272 273 274 /** 275 * Retrieves the DN of the user account on which to operate. 276 * 277 * @return The DN of the user account on which to operate. 278 */ 279 public String getUserDN() 280 { 281 return userDN; 282 } 283 284 285 286 /** 287 * Retrieves the set of password policy state operations to be processed. 288 * 289 * @return The set of password policy state operations to be processed, or 290 * an empty list if the values of all password policy state 291 * properties should be retrieved. 292 */ 293 public PasswordPolicyStateOperation[] getOperations() 294 { 295 return operations; 296 } 297 298 299 300 /** 301 * {@inheritDoc} 302 */ 303 @Override() 304 public PasswordPolicyStateExtendedResult 305 process(final LDAPConnection connection, final int depth) 306 throws LDAPException 307 { 308 final ExtendedResult extendedResponse = super.process(connection, depth); 309 return new PasswordPolicyStateExtendedResult(extendedResponse); 310 } 311 312 313 314 /** 315 * {@inheritDoc} 316 */ 317 @Override() 318 public PasswordPolicyStateExtendedRequest duplicate() 319 { 320 return duplicate(getControls()); 321 } 322 323 324 325 /** 326 * {@inheritDoc} 327 */ 328 @Override() 329 public PasswordPolicyStateExtendedRequest duplicate(final Control[] controls) 330 { 331 final PasswordPolicyStateExtendedRequest r = 332 new PasswordPolicyStateExtendedRequest(userDN, controls, operations); 333 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 334 return r; 335 } 336 337 338 339 /** 340 * {@inheritDoc} 341 */ 342 @Override() 343 public String getExtendedRequestName() 344 { 345 return INFO_EXTENDED_REQUEST_NAME_PW_POLICY_STATE.get(); 346 } 347 348 349 350 /** 351 * {@inheritDoc} 352 */ 353 @Override() 354 public void toString(final StringBuilder buffer) 355 { 356 buffer.append("PasswordPolicyStateExtendedRequest(userDN='"); 357 buffer.append(userDN); 358 359 if (operations.length > 0) 360 { 361 buffer.append("', operations={"); 362 for (int i=0; i < operations.length; i++) 363 { 364 if (i > 0) 365 { 366 buffer.append(", "); 367 } 368 369 operations[i].toString(buffer); 370 } 371 buffer.append('}'); 372 } 373 374 final Control[] controls = getControls(); 375 if (controls.length > 0) 376 { 377 buffer.append(", controls={"); 378 for (int i=0; i < controls.length; i++) 379 { 380 if (i > 0) 381 { 382 buffer.append(", "); 383 } 384 385 buffer.append(controls[i]); 386 } 387 buffer.append('}'); 388 } 389 390 buffer.append(')'); 391 } 392 }