/* * S. Bahloul & R. Ouazana * Copyright (C) 2003 LINAGORA * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.linagora.ldap.extended; import java.io.Serializable; import javax.naming.NamingException; import javax.naming.SizeLimitExceededException; import javax.naming.ldap.ExtendedRequest; import javax.naming.ldap.ExtendedResponse; /** * A class conforming to the ExtendedRequest that implements the * test modify extended operation. * * @see javax.naming.ldap.ExtendedRequest */ public class TestModifyLdapOperationRequest implements ExtendedRequest, Serializable { /** The OID of the test modify extended operation */ public static final String LDAP_EXOP_TEST_MODIFY = "1.3.6.1.4.1.13129.1.5.1"; /** The BER tag for */ public static final byte LDAP_TAG_EXOP_TEST_MODIFY_ATTRIBUTE = (byte) 0x80; /** The BER tag for */ public static final byte LDAP_TAG_EXOP_TEST_MODIFY_AUTHOR = (byte) 0x81; /** The BER tag for */ public static final byte LDAP_TAG_EXOP_TEST_MODIFY_TARGET = (byte) 0x82; /** The BER tag for */ public static final byte LDAP_TAG_EXOP_TEST_MODIFY_ISOK = (byte) 0x80; private static byte LDAP_TAG_SEQUENCE_START = (byte) 0x30; private static byte LDAP_TAG_VALID_VALUE = (byte) 0xFF; /** The size of ber_len_t */ public static final byte SIZE_OF_BER_LEN_T = (byte) 4; /** * Décode la berValue pour en tirer la donnée. * Le premier octet correspond au début d'une séquence. * Le second à la longueur du message. * Le troisième au nom de l'attribut. * Le quatrième à la longueur de l'attribut. * Le cinquième est la valeur. * On vérifie donc que * le premier octet vaut bien 0x30 et que * le troisième octet vaut bien LDAP_TAG_EXOP_TEST_MODIFY_ISOK * @param berValue * @param offset * @param length * @return true si ce cinquième byte vaut 1 */ public static boolean getOk(byte[] berValue, int offset, int length) { if ((berValue[0] == (byte) LDAP_TAG_SEQUENCE_START) && (berValue[2] == LDAP_TAG_EXOP_TEST_MODIFY_ISOK)) { return berValue[4] == (byte) LDAP_TAG_VALID_VALUE; } else { return false; } } /** The attribute to test to */ private String mAttr; /** The dn we want to test with */ private String mDnAuthor; /** The dn we want to test to */ private String mDnTarget; /** * Creates a new TestModifyRequest instance. * @param dn the dn of the author * @param dn the dn of the target whose attribute is to test * @param attr the attribute to test * @exception NullPointerException if dn or password is null * @exception SizeLimitExceededException when the dn or password * is too long */ public TestModifyLdapOperationRequest(String dnAuthor, String dnTarget, String attr) throws NullPointerException, SizeLimitExceededException { if (dnAuthor == null || dnTarget == null) { throw new NullPointerException("DN's cannot be null"); } if (attr == null) { throw new NullPointerException("Attribute cannot be null"); } mDnAuthor = dnAuthor; mDnTarget = dnTarget; mAttr = attr; } /** * Creates the extended response. With OpenLDAP, the extended * operation for test modification doesn't create a * response so we just return null here. * * @param id the OID of the response * @param berValue the BER encoded value of the response * @param offset the offset * @param length the length of the response * @return returns null as the modify password operation doesn't * generate a response. * @exception NamingException if an error occurs */ public ExtendedResponse createExtendedResponse(String id, byte[] berValue, int offset, int length) throws NamingException { return new TestModifyLdapOperationResponse(id, berValue, getOk(berValue, offset, length)); } /** * Get the BER encoded value for this operation. * This value contains the following bytes : * * Sequence tag (1) + sequence length (variable) + dnAuthor tag (1) + * dnAuthor length (1) + dnAuthor (variable) + dnTarget tag (1) + * dnTarget length (1) + dnTarget (variable) + attribute tag (1) + * attribute length (1) + attribute (variable) * * * @param mDnAuthor * @param mDnTarget * @param mAttr * @return a bytearray containing the BER sequence. */ public static byte[] getEncodedValue(String mDnAuthor, String mDnTarget, String mAttr) { try { int dataToWriteIndex; // Création de tableaux d'écriture byte[] headersToWrite = new byte[] { LDAP_TAG_EXOP_TEST_MODIFY_ATTRIBUTE, LDAP_TAG_EXOP_TEST_MODIFY_AUTHOR, LDAP_TAG_EXOP_TEST_MODIFY_TARGET }; byte[][] dataToWrite = new byte[][] { getBytesArray(mAttr), getBytesArray(mDnAuthor), getBytesArray(mDnTarget) }; // valeur temporaire de la longueur de cette longueur int tempLenlen; int length; int len = 6; // Calcul de la longueur en tenant compte de la longueur des longueurs des différents éléments for(dataToWriteIndex=0; dataToWriteIndex>= 8; } // writing the array of bytes for (int j = SIZE_OF_BER_LEN_T - (lenlen - 1) - 1; j <= SIZE_OF_BER_LEN_T - 1; j++) encoded[i++] = tmp[j]; } return i; } /** * @param dnAuthorLength */ private static void checkLength(String string, int length) throws SizeLimitExceededException { if (length <= 0) { throw new SizeLimitExceededException("value cannot be 0 length : "+string); } if (length > 0xFF) { throw new SizeLimitExceededException("value cannot be larger then 255 characters : "+string); } } /** * @param byteHeader * @param attr * @return */ private static int fillArrayAndMoveForward(byte[] arrayToFill, byte byteHeader, byte[] arrayToAdd, int i) throws SizeLimitExceededException { arrayToFill[i++] = byteHeader; int length = arrayToAdd.length; i = writeLenAndMoveForward(arrayToFill, getLenlen(length), length, i); System.arraycopy(arrayToAdd, 0, arrayToFill, i, arrayToAdd.length); i += arrayToAdd.length; return i; } /** * @param dnAuthor * @return */ private static byte[] getBytesArray(String value) throws SizeLimitExceededException { getLength(value); return value.getBytes(); } /** * Returns the ID of this extended operation. * * @return a String with the OID of this operation */ public String getID() { return LDAP_EXOP_TEST_MODIFY; } /** * @param dnAuthor * @return */ private static int getLength(String string) throws SizeLimitExceededException { int length = string.length(); checkLength(string, length); return length; } /** * @param len * @return length of len if len > 128, 0 else */ private static int getLenlen(int len) throws SizeLimitExceededException { int mask, i; if (len < 128) return 0; // Computing number of bytes in len for (i = SIZE_OF_BER_LEN_T - 1; i > 0; i--) { mask = (0xff << (i * 8)); if ((len & mask) != 0) break; } // Error if more than 4 bytes if (++i > 4) { throw new SizeLimitExceededException("The total length is too high"); } // Return number of bytes return i; } /** * @see javax.naming.ldap.ExtendedRequest#getEncodedValue() */ public byte[] getEncodedValue() { return getEncodedValue(mDnAuthor, mDnTarget, mAttr); } }