/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2008 Sun Microsystems, Inc.
*/
package org.opends.server.protocols.internal;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.ldap.*;
import org.opends.server.tools.LDAPReader;
import org.opends.server.tools.LDAPWriter;
import org.opends.server.types.*;
import static org.testng.Assert.*;
import static org.opends.server.util.ServerConstants.*;
/**
* This class provides a number of tests to cover the internal LDAP socket
* implementation.
*/
public class InternalLDAPSocketTestCase
extends InternalTestCase
{
/**
* Ensures that the Directory Server is running.
*
* @throws Exception If an unexpected problem occurs.
*/
@BeforeClass()
public void startServer()
throws Exception
{
TestCaseUtils.startServer();
}
/**
* Tests the ability to perform an add operation over the internal LDAP
* socket.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testAddOperation()
throws Exception
{
TestCaseUtils.initializeTestBackend(false);
assertFalse(DirectoryServer.entryExists(DN.decode("o=test")));
InternalLDAPSocket socket = new InternalLDAPSocket();
LDAPReader reader = new LDAPReader(socket);
LDAPWriter writer = new LDAPWriter(socket);
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
writer.writeMessage(message);
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getBindResponseProtocolOp().getResultCode(), 0);
ArrayList<RawAttribute> attrList = new ArrayList<RawAttribute>();
attrList.add(RawAttribute.create("objectClass", "organization"));
attrList.add(RawAttribute.create("o", "test"));
AddRequestProtocolOp addRequest =
new AddRequestProtocolOp(ByteString.valueOf("o=test"), attrList);
writer.writeMessage(new LDAPMessage(2, addRequest));
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getAddResponseProtocolOp().getResultCode(),
LDAPResultCode.SUCCESS);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
reader.close();
writer.close();
socket.close();
}
/**
* Tests the ability to perform an add operation over the internal LDAP
* socket via JNDI.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testAddOperationThroughJNDI()
throws Exception
{
TestCaseUtils.initializeTestBackend(false);
assertFalse(DirectoryServer.entryExists(DN.decode("o=test")));
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put("java.naming.ldap.factory.socket",
InternalLDAPSocketFactory.class.getName());
env.put(Context.PROVIDER_URL, "ldap://doesntmatter:389/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
env.put(Context.SECURITY_CREDENTIALS, "password");
env.put("com.sun.jndi.ldap.connect.pool.debug", "fine");
DirContext context = new InitialDirContext(env);
Attributes attributes = new BasicAttributes(true);
Attribute objectClass = new BasicAttribute("objectClass");
objectClass.add("top");
objectClass.add("organization");
attributes.put(objectClass);
Attribute o = new BasicAttribute("o");
o.add("test");
attributes.put(o);
context.createSubcontext("o=test", attributes);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
context.close();
}
/**
* Tests the ability to perform a compare operation over the internal LDAP
* socket.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testCompareOperation()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
InternalLDAPSocket socket = new InternalLDAPSocket();
LDAPReader reader = new LDAPReader(socket);
LDAPWriter writer = new LDAPWriter(socket);
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
writer.writeMessage(message);
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getBindResponseProtocolOp().getResultCode(), 0);
CompareRequestProtocolOp compareRequest =
new CompareRequestProtocolOp(ByteString.valueOf("o=test"), "o",
ByteString.valueOf("test"));
writer.writeMessage(new LDAPMessage(2, compareRequest));
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getCompareResponseProtocolOp().getResultCode(),
LDAPResultCode.COMPARE_TRUE);
reader.close();
writer.close();
socket.close();
}
/**
* Tests the ability to perform a compare operation over the internal LDAP
* socket via JNDI.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testCompareOperationThroughJNDI()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put("java.naming.ldap.factory.socket",
InternalLDAPSocketFactory.class.getName());
env.put(Context.PROVIDER_URL, "ldap://doesntmatter:389/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
env.put(Context.SECURITY_CREDENTIALS, "password");
DirContext context = new InitialDirContext(env);
SearchControls poorlyNamedSearchControls = new SearchControls();
poorlyNamedSearchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
poorlyNamedSearchControls.setReturningAttributes(new String[0]);
NamingEnumeration results = context.search("o=test", "(o=test)",
poorlyNamedSearchControls);
assertTrue(results.hasMoreElements());
assertNotNull(results.nextElement());
assertFalse(results.hasMoreElements());
context.close();
}
/**
* Tests the ability to perform a delete operation over the internal LDAP
* socket.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testDeleteOperation()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
InternalLDAPSocket socket = new InternalLDAPSocket();
LDAPReader reader = new LDAPReader(socket);
LDAPWriter writer = new LDAPWriter(socket);
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
writer.writeMessage(message);
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getBindResponseProtocolOp().getResultCode(), 0);
DeleteRequestProtocolOp deleteRequest =
new DeleteRequestProtocolOp(ByteString.valueOf("o=test"));
writer.writeMessage(new LDAPMessage(2, deleteRequest));
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getDeleteResponseProtocolOp().getResultCode(),
LDAPResultCode.SUCCESS);
assertFalse(DirectoryServer.entryExists(DN.decode("o=test")));
reader.close();
writer.close();
socket.close();
}
/**
* Tests the ability to perform a delete operation over the internal LDAP
* socket via JNDI.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testDeleteOperationThroughJNDI()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put("java.naming.ldap.factory.socket",
InternalLDAPSocketFactory.class.getName());
env.put(Context.PROVIDER_URL, "ldap://doesntmatter:389/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
env.put(Context.SECURITY_CREDENTIALS, "password");
DirContext context = new InitialDirContext(env);
context.destroySubcontext("o=test");
assertFalse(DirectoryServer.entryExists(DN.decode("o=test")));
context.close();
}
/**
* Tests the ability to perform an extended operation over the internal LDAP
* socket using the "Who Am I?" request.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testExtendedOperation()
throws Exception
{
InternalLDAPSocket socket = new InternalLDAPSocket();
LDAPReader reader = new LDAPReader(socket);
LDAPWriter writer = new LDAPWriter(socket);
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
writer.writeMessage(message);
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getBindResponseProtocolOp().getResultCode(), 0);
ExtendedRequestProtocolOp extendedRequest =
new ExtendedRequestProtocolOp(OID_WHO_AM_I_REQUEST);
writer.writeMessage(new LDAPMessage(2, extendedRequest));
message = reader.readMessage();
assertNotNull(message);
ExtendedResponseProtocolOp extendedResponse =
message.getExtendedResponseProtocolOp();
assertEquals(extendedResponse.getResultCode(), LDAPResultCode.SUCCESS);
assertTrue(extendedResponse.getValue().toString().equalsIgnoreCase(
"dn:cn=Directory Manager,cn=Root DNs,cn=config"));
reader.close();
writer.close();
socket.close();
}
/**
* Tests the ability to perform a modify operation over the internal LDAP
* socket.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testModifyOperation()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
InternalLDAPSocket socket = new InternalLDAPSocket();
LDAPReader reader = new LDAPReader(socket);
LDAPWriter writer = new LDAPWriter(socket);
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
writer.writeMessage(message);
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getBindResponseProtocolOp().getResultCode(), 0);
ArrayList<RawModification> mods = new ArrayList<RawModification>();
mods.add(RawModification.create(ModificationType.REPLACE, "description",
"foo"));
ModifyRequestProtocolOp modifyRequest =
new ModifyRequestProtocolOp(ByteString.valueOf("o=test"), mods);
writer.writeMessage(new LDAPMessage(2, modifyRequest));
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getModifyResponseProtocolOp().getResultCode(),
LDAPResultCode.SUCCESS);
reader.close();
writer.close();
socket.close();
}
/**
* Tests the ability to perform a modify operation over the internal LDAP
* socket via JNDI.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testModifyOperationThroughJNDI()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put("java.naming.ldap.factory.socket",
InternalLDAPSocketFactory.class.getName());
env.put(Context.PROVIDER_URL, "ldap://doesntmatter:389/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
env.put(Context.SECURITY_CREDENTIALS, "password");
DirContext context = new InitialDirContext(env);
ModificationItem[] mods =
{
new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
new BasicAttribute("description", "foo"))
};
context.modifyAttributes("o=test", mods);
context.close();
}
/**
* Tests the ability to perform a modify DN operation over the internal LDAP
* socket.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testModifyDNOperation()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
assertTrue(DirectoryServer.entryExists(DN.decode("ou=People,o=test")));
assertFalse(DirectoryServer.entryExists(DN.decode("ou=Users,o=test")));
InternalLDAPSocket socket = new InternalLDAPSocket();
LDAPReader reader = new LDAPReader(socket);
LDAPWriter writer = new LDAPWriter(socket);
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
writer.writeMessage(message);
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getBindResponseProtocolOp().getResultCode(), 0);
ModifyDNRequestProtocolOp modifyDNRequest =
new ModifyDNRequestProtocolOp(ByteString.valueOf("ou=People,o=test"),
ByteString.valueOf("ou=Users"), true);
writer.writeMessage(new LDAPMessage(2, modifyDNRequest));
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getModifyDNResponseProtocolOp().getResultCode(),
LDAPResultCode.SUCCESS);
assertFalse(DirectoryServer.entryExists(DN.decode("ou=People,o=test")));
assertTrue(DirectoryServer.entryExists(DN.decode("ou=Users,o=test")));
reader.close();
writer.close();
socket.close();
}
/**
* Tests the ability to perform a modify DN operation over the internal LDAP
* socket via JNDI.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testModifyDNOperationThroughJNDI()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntry(
"dn: ou=People,o=test",
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People");
assertTrue(DirectoryServer.entryExists(DN.decode("ou=People,o=test")));
assertFalse(DirectoryServer.entryExists(DN.decode("ou=Users,o=test")));
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put("java.naming.ldap.factory.socket",
InternalLDAPSocketFactory.class.getName());
env.put(Context.PROVIDER_URL, "ldap://doesntmatter:389/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
env.put(Context.SECURITY_CREDENTIALS, "password");
DirContext context = new InitialDirContext(env);
context.rename("ou=People,o=test", "ou=Users,o=test");
assertFalse(DirectoryServer.entryExists(DN.decode("ou=People,o=test")));
assertTrue(DirectoryServer.entryExists(DN.decode("ou=Users,o=test")));
context.close();
}
/**
* Tests the ability to perform a search operation over the internal LDAP
* socket.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testSearchOperation()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
InternalLDAPSocket socket = new InternalLDAPSocket();
LDAPReader reader = new LDAPReader(socket);
LDAPWriter writer = new LDAPWriter(socket);
BindRequestProtocolOp bindRequest =
new BindRequestProtocolOp(ByteString.valueOf("cn=Directory Manager"),
3, ByteString.valueOf("password"));
LDAPMessage message = new LDAPMessage(1, bindRequest);
writer.writeMessage(message);
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getBindResponseProtocolOp().getResultCode(), 0);
SearchRequestProtocolOp searchRequest =
new SearchRequestProtocolOp(ByteString.valueOf("o=test"),
SearchScope.BASE_OBJECT,
DereferencePolicy.NEVER_DEREF_ALIASES,
0, 0, false,
LDAPFilter.decode("(objectClass=*)"),
new LinkedHashSet<String>());
writer.writeMessage(new LDAPMessage(2, searchRequest));
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getSearchResultEntryProtocolOp().getDN(),
DN.decode("o=test"));
message = reader.readMessage();
assertNotNull(message);
assertEquals(message.getSearchResultDoneProtocolOp().getResultCode(),
LDAPResultCode.SUCCESS);
reader.close();
writer.close();
socket.close();
}
/**
* Tests the ability to perform a searcj operation over the internal LDAP
* socket via JNDI.
*
* @throws Exception If an unexpected problem occurs.
*/
@Test()
public void testSearchOperationThroughJNDI()
throws Exception
{
TestCaseUtils.initializeTestBackend(true);
assertTrue(DirectoryServer.entryExists(DN.decode("o=test")));
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put("java.naming.ldap.factory.socket",
InternalLDAPSocketFactory.class.getName());
env.put(Context.PROVIDER_URL, "ldap://doesntmatter:389/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=Directory Manager");
env.put(Context.SECURITY_CREDENTIALS, "password");
DirContext context = new InitialDirContext(env);
SearchControls poorlyNamedSearchControls = new SearchControls();
poorlyNamedSearchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
NamingEnumeration results = context.search("o=test", "(objectClass=*)",
poorlyNamedSearchControls);
assertTrue(results.hasMoreElements());
assertNotNull(results.nextElement());
assertFalse(results.hasMoreElements());
context.close();
}
}