| 
					
				 | 
			
			
				@@ -1,360 +0,0 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * 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. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-package org.acegisecurity.providers.ldap.authenticator.controls; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import netscape.ldap.ber.stream.BERChoice; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import netscape.ldap.ber.stream.BERElement; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import netscape.ldap.ber.stream.BEREnumerated; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import netscape.ldap.ber.stream.BERInteger; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//import com.novell.ldap.asn1.LBERDecoder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//import com.novell.ldap.asn1.ASN1Sequence; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//import com.novell.ldap.asn1.ASN1Tagged; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//import com.novell.ldap.asn1.ASN1OctetString; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import netscape.ldap.ber.stream.BERSequence; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import netscape.ldap.ber.stream.BERTag; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import netscape.ldap.ber.stream.BERTagDecoder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.acegisecurity.ldap.LdapDataAccessException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.apache.commons.logging.Log; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import org.apache.commons.logging.LogFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import java.io.ByteArrayInputStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import java.io.IOException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import java.io.InputStream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * Represent the response control received when a <tt>PasswordPolicyControl</tt> is used when binding to a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * directory. Currently tested with the OpenLDAP 2.3.19 implementation of the LDAP Password Policy Draft.  It extends 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * the request control with the control specific data. This is accomplished by the properties timeBeforeExpiration, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * graceLoginsRemaining and errorCodes. getEncodedValue returns the unchanged value of the response control as a byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @author Stefan Zoerner 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @author Luke Taylor 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @version $Id$ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @see PasswordPolicyControl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @see <a href="http://www.ibm.com/developerworks/tivoli/library/t-ldap-controls/">Stefan Zoerner's IBM developerworks 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- *      article on LDAP controls.</a> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class PasswordPolicyResponseControl extends PasswordPolicyControl { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //~ Static fields/initializers ===================================================================================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private static final Log logger = LogFactory.getLog(PasswordPolicyResponseControl.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public static final int ERROR_NONE = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public static final int ERROR_PASSWORD_EXPIRED = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public static final int ERROR_ACCOUNT_LOCKED = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public static final int WARNINGS_DEFAULT = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private static final String[] errorText = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            "password expired", "account locked", "change after reset", "password mod not allowed", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            "must supply old password", "invalid password syntax", "password too short", "password too young", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            "password in history" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //~ Instance fields ================================================================================================ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private byte[] encodedValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private int errorCode = ERROR_NONE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private int graceLoginsRemaining = WARNINGS_DEFAULT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private int timeBeforeExpiration = WARNINGS_DEFAULT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //~ Constructors =================================================================================================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public PasswordPolicyResponseControl(byte[] encodedValue) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.encodedValue = encodedValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //PPolicyDecoder decoder = new JLdapDecoder(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        PPolicyDecoder decoder = new NetscapeDecoder(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            decoder.decode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } catch (IOException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            throw new LdapDataAccessException("Failed to parse control value", e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //~ Methods ======================================================================================================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Returns the unchanged value of the response control.  Returns the unchanged value of the response 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * control as byte array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return DOCUMENT ME! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public byte[] getEncodedValue() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return encodedValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Returns the error code, or ERROR_NONE, if no error is present. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return the error code (0-8), or ERROR_NONE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public int getErrorCode() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return errorCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Decodes the Ber encoded control data. The ASN.1 value of the control data is:<pre> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     *    PasswordPolicyResponseValue ::= SEQUENCE {       warning [0] CHOICE { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     *           timeBeforeExpiration [0] INTEGER (0 .. maxInt), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     *           graceAuthNsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL,       error   [1] ENUMERATED { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     *           passwordExpired             (0),          accountLocked               (1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     *           changeAfterReset            (2),          passwordModNotAllowed       (3), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     *           mustSupplyOldPassword       (4),          insufficientPasswordQuality (5), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     *           passwordTooShort            (6),          passwordTooYoung            (7), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     *           passwordInHistory           (8) } OPTIONAL }</pre> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return DOCUMENT ME! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Returns the graceLoginsRemaining. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return Returns the graceLoginsRemaining. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public int getGraceLoginsRemaining() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return graceLoginsRemaining; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Returns the timeBeforeExpiration. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return Returns the time before expiration in seconds 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public int getTimeBeforeExpiration() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return timeBeforeExpiration; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Checks whether an error is present. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return true, if an error is present 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public boolean hasError() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return this.getErrorCode() != ERROR_NONE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Checks whether a warning is present. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return true, if a warning is present 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public boolean hasWarning() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return (graceLoginsRemaining != WARNINGS_DEFAULT) || (timeBeforeExpiration != WARNINGS_DEFAULT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public boolean isExpired() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return errorCode == ERROR_PASSWORD_EXPIRED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Determines whether an account locked error has been returned. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return true if the account is locked. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public boolean isLocked() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return errorCode == ERROR_ACCOUNT_LOCKED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Create a textual representation containing error and warning messages, if any are present. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * @return error and warning messages 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public String toString() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        StringBuffer sb = new StringBuffer("PasswordPolicyResponseControl"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (hasError()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            sb.append(", error: ").append(errorText[errorCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (graceLoginsRemaining != WARNINGS_DEFAULT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            sb.append(", warning: ").append(graceLoginsRemaining).append(" grace logins remain"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (timeBeforeExpiration != WARNINGS_DEFAULT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            sb.append(", warning: time before expiration is ").append(timeBeforeExpiration); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!hasError() && !hasWarning()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            sb.append(" (no error, no warning)"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return sb.toString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //~ Inner Interfaces =============================================================================================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private interface PPolicyDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        void decode() throws IOException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //~ Inner Classes ================================================================================================== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     * Decoder based on Netscape ldapsdk library 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private class NetscapeDecoder implements PPolicyDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        public void decode() throws IOException { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            int[] bread = {0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            BERSequence seq = (BERSequence) BERElement.getElement(new SpecificTagDecoder(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    new ByteArrayInputStream(encodedValue), bread); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            int size = seq.size(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (logger.isDebugEnabled()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                logger.debug("PasswordPolicyResponse, ASN.1 sequence has " + size + " elements"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            for (int i = 0; i < seq.size(); i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                BERTag elt = (BERTag) seq.elementAt(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                int tag = elt.getTag() & 0x1F; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (tag == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    BERChoice warning = (BERChoice) elt.getValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    BERTag content = (BERTag) warning.getValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    int value = ((BERInteger) content.getValue()).getValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if ((content.getTag() & 0x1F) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        timeBeforeExpiration = value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        graceLoginsRemaining = value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } else if (tag == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    BEREnumerated error = (BEREnumerated) elt.getValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    errorCode = error.getValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        class SpecificTagDecoder extends BERTagDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            /** Allows us to remember which of the two options we're decoding */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            private Boolean inChoice = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            public BERElement getElement(BERTagDecoder decoder, int tag, InputStream stream, int[] bytesRead, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                boolean[] implicit) throws IOException { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                tag &= 0x1F; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                implicit[0] = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (tag == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // Either the choice or the time before expiry within it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (inChoice == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        setInChoice(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // Read the choice length from the stream (ignored) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        BERElement.readLengthOctets(stream, bytesRead); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        int[] componentLength = new int[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        BERElement choice = new BERChoice(decoder, stream, componentLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        bytesRead[0] += componentLength[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // inChoice = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        return choice; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // Must be time before expiry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        return new BERInteger(stream, bytesRead); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } else if (tag == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // Either the graceLogins or the error enumeration. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (inChoice == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // The enumeration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        setInChoice(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        return new BEREnumerated(stream, bytesRead); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if (inChoice.booleanValue()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            // graceLogins 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            return new BERInteger(stream, bytesRead); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                throw new LdapDataAccessException("Unexpected tag " + tag); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            private void setInChoice(boolean inChoice) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                this.inChoice = new Boolean(inChoice); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** Decoder based on the OpenLDAP/Novell JLDAP library */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//    private class JLdapDecoder implements PPolicyDecoder { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//        public void decode() throws IOException { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            LBERDecoder decoder = new LBERDecoder(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            ASN1Sequence seq = (ASN1Sequence)decoder.decode(encodedValue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            if(seq == null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            int size = seq.size(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            if(logger.isDebugEnabled()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                logger.debug("PasswordPolicyResponse, ASN.1 sequence has " + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                        size + " elements"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            for(int i=0; i < size; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                ASN1Tagged taggedObject = (ASN1Tagged)seq.get(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                int tag = taggedObject.getIdentifier().getTag(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                ASN1OctetString value = (ASN1OctetString)taggedObject.taggedValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                byte[] content = value.byteValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                if(tag == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                    parseWarning(content, decoder); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                } else if(tag == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                    // Error: set the code to the value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                    errorCode = content[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//        private void parseWarning(byte[] content, LBERDecoder decoder) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            // It's the warning (choice). Parse the number and set either the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            // expiry time or number of logins remaining. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            ASN1Tagged taggedObject = (ASN1Tagged)decoder.decode(content); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            int contentTag = taggedObject.getIdentifier().getTag(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            content = ((ASN1OctetString)taggedObject.taggedValue()).byteValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            int number; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                number = ((Long)decoder.decodeNumeric(new ByteArrayInputStream(content), content.length)).intValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            } catch(IOException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                throw new LdapDataAccessException("Failed to parse number ", e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            if(contentTag == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                timeBeforeExpiration = number; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            } else if (contentTag == 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//                graceLoginsRemaining = number; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-//    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 |