You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by de...@apache.org on 2011/07/15 12:13:09 UTC

svn commit: r1147073 - in /activemq/trunk/activemq-core: ./ src/main/java/org/apache/activemq/security/ src/test/java/org/apache/activemq/security/ src/test/resources/org/apache/activemq/security/

Author: dejanb
Date: Fri Jul 15 10:13:08 2011
New Revision: 1147073

URL: http://svn.apache.org/viewvc?rev=1147073&view=rev
Log:
https://issues.apache.org/jira/browse/AMQ-3400 - cached ldap autorization module

Added:
    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/security/CachedLDAPAuthorizationMap.java
    activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPAuthorizationModuleTest.java
    activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPSecurityTest.java
    activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.ldif
    activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.xml
    activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.ldif
    activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.xml
    activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/add.ldif
    activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/delete.ldif
Modified:
    activemq/trunk/activemq-core/pom.xml

Modified: activemq/trunk/activemq-core/pom.xml
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/pom.xml?rev=1147073&r1=1147072&r2=1147073&view=diff
==============================================================================
--- activemq/trunk/activemq-core/pom.xml (original)
+++ activemq/trunk/activemq-core/pom.xml Fri Jul 15 10:13:08 2011
@@ -463,6 +463,8 @@
             <!--  exclude until we fix problems with apache ds and maven  -->
             <exclude>**/LDAPAuthorizationMapTest.*</exclude>
             <exclude>**/LDAPSecurityTest.*</exclude>
+            <exclude>**/CachedLDAPAuthorizationModuleTest.*</exclude>
+            <exclude>**/CachedLDAPSecurityTest.*</exclude>
 
             <!-- http://issues.apache.org/activemq/browse/AMQ-1027 -->
             <exclude>**/FailoverConsumerTest.*</exclude>

Added: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/security/CachedLDAPAuthorizationMap.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/security/CachedLDAPAuthorizationMap.java?rev=1147073&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/security/CachedLDAPAuthorizationMap.java (added)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/security/CachedLDAPAuthorizationMap.java Fri Jul 15 10:13:08 2011
@@ -0,0 +1,366 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.activemq.security;
+
+import org.apache.activemq.command.ActiveMQDestination;
+import org.apache.activemq.command.ActiveMQQueue;
+import org.apache.activemq.command.ActiveMQTopic;
+import org.apache.activemq.filter.DestinationMapNode;
+import org.apache.activemq.filter.DestinationNode;
+import org.apache.activemq.jaas.GroupPrincipal;
+import org.apache.activemq.security.AuthorizationEntry;
+import org.apache.activemq.security.DefaultAuthorizationMap;
+import org.apache.activemq.security.TempDestinationAuthorizationEntry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.*;
+import javax.naming.event.*;
+import java.util.*;
+
+public class CachedLDAPAuthorizationMap extends DefaultAuthorizationMap implements NamespaceChangeListener,
+        ObjectChangeListener, InitializingBean {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CachedLDAPAuthorizationMap.class);
+
+
+    private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
+    private String connectionURL = "ldap://localhost:1024";
+    private String connectionUsername = "uid=admin,ou=system";
+    private String connectionPassword = "secret";
+    private String connectionProtocol = "s";
+    private String authentication = "simple";
+
+    private String baseDn = "ou=system";
+    private int cnsLength = 5;
+
+    private int refreshInterval = -1;
+    private long lastUpdated;
+
+    private static String ANY_DESCENDANT = "\\$";
+
+    private DirContext context;
+    private EventDirContext eventContext;
+
+    protected DirContext open() throws NamingException {
+        if (context != null) {
+            return context;
+        }
+
+        try {
+            Hashtable<String, String> env = new Hashtable<String, String>();
+            env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
+            if (connectionUsername != null || !"".equals(connectionUsername)) {
+                env.put(Context.SECURITY_PRINCIPAL, connectionUsername);
+            }
+            if (connectionPassword != null || !"".equals(connectionPassword)) {
+                env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
+            }
+            env.put(Context.SECURITY_PROTOCOL, connectionProtocol);
+            env.put(Context.PROVIDER_URL, connectionURL);
+            env.put(Context.SECURITY_AUTHENTICATION, authentication);
+            context = new InitialDirContext(env);
+
+
+            if (refreshInterval == -1) {
+                eventContext = ((EventDirContext)context.lookup(""));
+                final SearchControls constraints = new SearchControls();
+                constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
+                LOG.debug("Listening for: " + "'ou=Destination,ou=ActiveMQ," + baseDn + "'");
+                eventContext.addNamingListener("ou=Destination,ou=ActiveMQ," + baseDn, "cn=*", constraints, this);
+            }
+        } catch (NamingException e) {
+            LOG.error(e.toString());
+            throw e;
+        }
+        return context;
+    }
+
+
+    HashMap<ActiveMQDestination, AuthorizationEntry> entries = new HashMap<ActiveMQDestination, AuthorizationEntry>();
+
+
+    public void query() throws Exception {
+        try {
+            context = open();
+        } catch (NamingException e) {
+            LOG.error(e.toString());
+        }
+
+        final SearchControls constraints = new SearchControls();
+        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+        NamingEnumeration results = context.search("ou=Destination,ou=ActiveMQ," + baseDn, "(|(cn=admin)(cn=write)(cn=read))", constraints);
+        while (results.hasMore()) {
+            SearchResult result = (SearchResult) results.next();
+            AuthorizationEntry entry = getEntry(result.getNameInNamespace());
+            applyACL(entry, result);
+        }
+
+        setEntries(new ArrayList(entries.values()));
+        updated();
+    }
+
+    protected void updated() {
+        lastUpdated = System.currentTimeMillis();
+    }
+
+    protected AuthorizationEntry getEntry(String name) {;
+            String[] cns = name.split(",");
+
+            // handle temp entry
+            if (cns.length == cnsLength && cns[1].equals("ou=Temp")) {
+                TempDestinationAuthorizationEntry tempEntry = getTempDestinationAuthorizationEntry();
+                if (tempEntry == null) {
+                    tempEntry = new TempDestinationAuthorizationEntry();
+                    setTempDestinationAuthorizationEntry(tempEntry);
+                }
+                return tempEntry;
+            }
+
+            // handle regular destinations
+            if (cns.length != (cnsLength + 1)) {
+                LOG.warn("Policy not applied! Wrong cn for authorization entry " + name);
+            }
+
+            ActiveMQDestination dest = formatDestination(cns[1], cns[2]);
+
+            if (dest != null) {
+                AuthorizationEntry entry = entries.get(dest);
+                if (entry == null) {
+                    entry = new AuthorizationEntry();
+                    entry.setDestination(dest);
+                    entries.put(dest, entry);
+                }
+                return entry;
+            } else {
+                return null;
+            }
+    }
+
+    protected ActiveMQDestination formatDestination(String destinationName, String destinationType) {
+            ActiveMQDestination dest = null;
+            if (destinationType.equalsIgnoreCase("ou=queue")) {
+               dest = new ActiveMQQueue(formatDestinationName(destinationName));
+            } else if (destinationType.equalsIgnoreCase("ou=topic")) {
+               dest = new ActiveMQTopic(formatDestinationName(destinationName));
+            } else {
+                LOG.warn("Policy not applied! Unknown destination type " + destinationType);
+            }
+            return dest;
+    }
+
+    protected void applyACL(AuthorizationEntry entry, SearchResult result) throws NamingException {
+        // find members
+        Attribute cn = result.getAttributes().get("cn");
+        Attribute member = result.getAttributes().get("member");
+        NamingEnumeration memberEnum = member.getAll();
+        HashSet members = new HashSet();
+        while (memberEnum.hasMoreElements()) {
+            String elem = (String) memberEnum.nextElement();
+            members.add(new GroupPrincipal(elem.replaceAll("cn=", "")));
+        }
+
+        // apply privilege
+        if (cn.get().equals("admin")) {
+            entry.setAdminACLs(members);
+        } else if (cn.get().equals("write")) {
+            entry.setWriteACLs(members);
+        } else if (cn.get().equals("read")) {
+            entry.setReadACLs(members);
+        } else {
+            LOG.warn("Policy not applied! Unknown privilege " + result.getName());
+        }
+    }
+
+    protected String formatDestinationName(String cn) {
+        return cn.replaceFirst("cn=", "").replaceAll(ANY_DESCENDANT, ">");
+    }
+
+    protected boolean isPriviledge(Binding binding) {
+        String name = binding.getName();
+        if (name.startsWith("cn=admin") || name.startsWith("cn=write") || name.startsWith("cn=read")) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    protected Set<AuthorizationEntry> getAllEntries(ActiveMQDestination destination) {
+        if (refreshInterval != -1 && System.currentTimeMillis() >= lastUpdated + refreshInterval) {
+
+            reset();
+            entries.clear();
+
+            LOG.debug("Updating authorization map!");
+            try {
+                query();
+            } catch (Exception e) {
+                LOG.error("Error updating authorization map", e);
+            }
+        }
+
+        return super.getAllEntries(destination);
+    }
+
+    @Override
+    public void objectAdded(NamingEvent namingEvent) {
+        LOG.debug("Adding object: " + namingEvent.getNewBinding());
+        SearchResult result = (SearchResult)namingEvent.getNewBinding();
+        String cn = null;
+        if (!isPriviledge(result)) return;
+        AuthorizationEntry entry = getEntry(result.getName());
+        if (entry != null) {
+            try {
+                applyACL(entry, result);
+                if (!(entry instanceof TempDestinationAuthorizationEntry)) {
+                    put(entry.getDestination(), entry);
+                }
+            } catch (NamingException ne) {
+                LOG.warn("Unable to add entry", ne);
+            }
+        }
+    }
+
+    @Override
+    public void objectRemoved(NamingEvent namingEvent) {
+        LOG.debug("Removing object: " + namingEvent.getOldBinding());
+        Binding result = namingEvent.getOldBinding();
+        if (!isPriviledge(result)) return;
+        AuthorizationEntry entry = getEntry(result.getName());
+        String[] cns = result.getName().split(",");
+        if (!isPriviledge(result)) return;
+        if (cns[0].equalsIgnoreCase("cn=admin")) {
+            entry.setAdminACLs(new HashSet());
+        } else if (cns[0].equalsIgnoreCase("cn=write")) {
+            entry.setWriteACLs(new HashSet());
+        } else if (cns[0].equalsIgnoreCase("cn=read")) {
+            entry.setReadACLs(new HashSet());
+        } else {
+            LOG.warn("Policy not removed! Unknown privilege " + result.getName());
+        }
+    }
+
+    @Override
+    public void objectRenamed(NamingEvent namingEvent) {
+        Binding oldBinding = namingEvent.getOldBinding();
+        Binding newBinding = namingEvent.getNewBinding();
+        LOG.debug("Renaming object: " + oldBinding + " to " + newBinding);
+
+        String[] oldCns = oldBinding.getName().split(",");
+        ActiveMQDestination oldDest = formatDestination(oldCns[0], oldCns[1]);
+
+        String[] newCns = newBinding.getName().split(",");
+        ActiveMQDestination newDest = formatDestination(newCns[0], newCns[1]);
+
+        if (oldDest != null && newDest != null) {
+            AuthorizationEntry entry = entries.remove(oldDest);
+            if (entry != null) {
+                entry.setDestination(newDest);
+                put(newDest, entry);
+                remove(oldDest, entry);
+            } else {
+                LOG.warn("No authorization entry for " + oldDest);
+            }
+        }
+    }
+
+    @Override
+    public void objectChanged(NamingEvent namingEvent) {
+        LOG.debug("Changing object " + namingEvent.getOldBinding() + " to " + namingEvent.getNewBinding());
+        objectRemoved(namingEvent);
+        objectAdded(namingEvent);
+    }
+
+    @Override
+    public void namingExceptionThrown(NamingExceptionEvent namingExceptionEvent) {
+        LOG.error("Caught Unexpected Exception", namingExceptionEvent.getException());
+    }
+
+    // init
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        query();
+    }
+
+    // getters and setters
+
+    public String getConnectionURL() {
+        return connectionURL;
+    }
+
+    public void setConnectionURL(String connectionURL) {
+        this.connectionURL = connectionURL;
+    }
+
+    public String getConnectionUsername() {
+        return connectionUsername;
+    }
+
+    public void setConnectionUsername(String connectionUsername) {
+        this.connectionUsername = connectionUsername;
+    }
+
+    public String getConnectionPassword() {
+        return connectionPassword;
+    }
+
+    public void setConnectionPassword(String connectionPassword) {
+        this.connectionPassword = connectionPassword;
+    }
+
+    public String getConnectionProtocol() {
+        return connectionProtocol;
+    }
+
+    public void setConnectionProtocol(String connectionProtocol) {
+        this.connectionProtocol = connectionProtocol;
+    }
+
+    public String getAuthentication() {
+        return authentication;
+    }
+
+    public void setAuthentication(String authentication) {
+        this.authentication = authentication;
+    }
+
+    public String getBaseDn() {
+        return baseDn;
+    }
+
+    public void setBaseDn(String baseDn) {
+        this.baseDn = baseDn;
+        cnsLength = baseDn.split(",").length + 4;
+    }
+
+    public int getRefreshInterval() {
+        return refreshInterval;
+    }
+
+    public void setRefreshInterval(int refreshInterval) {
+        this.refreshInterval = refreshInterval;
+    }
+}
+

Added: activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPAuthorizationModuleTest.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPAuthorizationModuleTest.java?rev=1147073&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPAuthorizationModuleTest.java (added)
+++ activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPAuthorizationModuleTest.java Fri Jul 15 10:13:08 2011
@@ -0,0 +1,234 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.activemq.security;
+
+import org.apache.activemq.command.ActiveMQQueue;
+import org.apache.activemq.command.ActiveMQTopic;
+import org.apache.activemq.jaas.GroupPrincipal;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.message.BindResponse;
+import org.apache.directory.ldap.client.api.message.ModifyDnResponse;
+import org.apache.directory.ldap.client.api.message.ModifyRequest;
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ApplyLdifFiles;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.apache.directory.shared.ldap.ldif.LdifEntry;
+import org.apache.directory.shared.ldap.ldif.LdifReader;
+import org.apache.directory.shared.ldap.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.name.DN;
+import org.apache.directory.shared.ldap.name.RDN;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+
+
+
+
+@RunWith( FrameworkRunner.class )
+@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP")})
+@ApplyLdifFiles(
+        "org/apache/activemq/security/activemq-apacheds.ldif"
+)
+public class CachedLDAPAuthorizationModuleTest extends AbstractLdapTestUnit {
+
+    static final GroupPrincipal GUESTS = new GroupPrincipal("guests");
+    static final GroupPrincipal USERS = new GroupPrincipal("users");
+    static final GroupPrincipal ADMINS = new GroupPrincipal("admins");
+
+    @Test
+    public void testQuery() throws Exception {
+        CachedLDAPAuthorizationMap map = new CachedLDAPAuthorizationMap();
+        map.query();
+        Set readACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
+        assertEquals("set size: " + readACLs, 2, readACLs.size());
+        assertTrue("Contains admin group", readACLs.contains(ADMINS));
+        assertTrue("Contains users group", readACLs.contains(USERS));
+
+        Set failedACLs = map.getReadACLs(new ActiveMQQueue("FAILED"));
+        assertEquals("set size: " + failedACLs, 0, failedACLs.size());
+    }
+
+
+    @Test
+    public void testWildcards() throws Exception {
+        CachedLDAPAuthorizationMap map1 = new CachedLDAPAuthorizationMap();
+        map1.query();
+        Set fooACLs = map1.getReadACLs(new ActiveMQQueue("FOO.1"));
+        assertEquals("set size: " + fooACLs, 2, fooACLs.size());
+        assertTrue("Contains admin group", fooACLs.contains(ADMINS));
+        assertTrue("Contains users group", fooACLs.contains(USERS));
+
+        CachedLDAPAuthorizationMap map2 = new CachedLDAPAuthorizationMap();
+        map2.query();
+        Set barACLs = map2.getReadACLs(new ActiveMQQueue("BAR.2"));
+        assertEquals("set size: " + barACLs, 2, barACLs.size());
+        assertTrue("Contains admin group", barACLs.contains(ADMINS));
+        assertTrue("Contains users group", barACLs.contains(USERS));
+    }
+
+    @Test
+    public void testAdvisory() throws Exception {
+        CachedLDAPAuthorizationMap map = new CachedLDAPAuthorizationMap();
+        map.query();
+        Set readACLs = map.getReadACLs(new ActiveMQTopic("ActiveMQ.Advisory.Connection"));
+        assertEquals("set size: " + readACLs, 2, readACLs.size());
+        assertTrue("Contains admin group", readACLs.contains(ADMINS));
+        assertTrue("Contains users group", readACLs.contains(USERS));
+    }
+
+    @Test
+    public void testTemporary() throws Exception {
+        CachedLDAPAuthorizationMap map = new CachedLDAPAuthorizationMap();
+        map.query();
+        Thread.sleep(1000);
+        Set readACLs = map.getTempDestinationReadACLs();
+        assertEquals("set size: " + readACLs, 2, readACLs.size());
+        assertTrue("Contains admin group", readACLs.contains(ADMINS));
+        assertTrue("Contains users group", readACLs.contains(USERS));
+    }
+
+    @Test
+    public void testAdd() throws Exception {
+        CachedLDAPAuthorizationMap map = new CachedLDAPAuthorizationMap();
+        map.query();
+
+        Set failedACLs = map.getReadACLs(new ActiveMQQueue("FAILED"));
+        assertEquals("set size: " + failedACLs, 0, failedACLs.size());
+
+        LdapConnection connection = new LdapConnection( "localhost", 1024 );
+        BindResponse bindResponse = connection.bind("uid=admin,ou=system", "secret");
+        assertNotNull(bindResponse);
+        assertEquals(ResultCodeEnum.SUCCESS, bindResponse.getLdapResult().getResultCode());
+        assertTrue(connection.isAuthenticated());
+
+
+        LdifReader reader = new LdifReader(getClass().getClassLoader().getResourceAsStream("org/apache/activemq/security/add.ldif"));
+
+        List<LdifEntry> entries = service.getTestEntries();
+        for (LdifEntry entry : reader) {
+            connection.add(entry.getEntry());
+
+        }
+
+        Thread.sleep(2000);
+
+        failedACLs = map.getReadACLs(new ActiveMQQueue("FAILED"));
+        assertEquals("set size: " + failedACLs, 2, failedACLs.size());
+
+        connection.close();
+
+
+    }
+
+    @Test
+    public void testRemove() throws Exception {
+        CachedLDAPAuthorizationMap map = new CachedLDAPAuthorizationMap();
+        map.query();
+
+        Set failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
+        assertEquals("set size: " + failedACLs, 2, failedACLs.size());
+
+        LdapConnection connection = new LdapConnection( "localhost", 1024 );
+        BindResponse bindResponse = connection.bind("uid=admin,ou=system", "secret");
+        assertNotNull(bindResponse);
+        assertEquals(ResultCodeEnum.SUCCESS, bindResponse.getLdapResult().getResultCode());
+        assertTrue(connection.isAuthenticated());
+
+
+        LdifReader reader = new LdifReader(getClass().getClassLoader().getResourceAsStream("org/apache/activemq/security/delete.ldif"));
+
+        List<LdifEntry> entries = service.getTestEntries();
+        for (LdifEntry entry : reader) {
+            connection.delete(entry.getDn());
+        }
+
+        Thread.sleep(2000);
+
+        failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
+        assertEquals("set size: " + failedACLs, 0, failedACLs.size());
+
+        connection.close();
+    }
+
+    @Test
+    public void testRename() throws Exception {
+        CachedLDAPAuthorizationMap map = new CachedLDAPAuthorizationMap();
+        map.query();
+
+        Set failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
+        assertEquals("set size: " + failedACLs, 2, failedACLs.size());
+
+        LdapConnection connection = new LdapConnection( "localhost", 1024 );
+        BindResponse bindResponse = connection.bind("uid=admin,ou=system", "secret");
+        assertNotNull(bindResponse);
+        assertEquals(ResultCodeEnum.SUCCESS, bindResponse.getLdapResult().getResultCode());
+        assertTrue(connection.isAuthenticated());
+
+        ModifyDnResponse resp = connection.rename(new DN("cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system"),
+                new RDN("cn=TEST.BAR"));
+
+        Thread.sleep(2000);
+
+        failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
+        assertEquals("set size: " + failedACLs, 0, failedACLs.size());
+
+
+        failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.BAR"));
+        assertEquals("set size: " + failedACLs, 2, failedACLs.size());
+
+        connection.close();
+    }
+
+    @Test
+    public void testChange() throws Exception {
+        CachedLDAPAuthorizationMap map = new CachedLDAPAuthorizationMap();
+        map.query();
+
+        Set failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
+        assertEquals("set size: " + failedACLs, 2, failedACLs.size());
+
+        LdapConnection connection = new LdapConnection( "localhost", 1024 );
+        BindResponse bindResponse = connection.bind("uid=admin,ou=system", "secret");
+        assertNotNull(bindResponse);
+        assertEquals(ResultCodeEnum.SUCCESS, bindResponse.getLdapResult().getResultCode());
+        assertTrue(connection.isAuthenticated());
+
+        DN dn = new DN("cn=read,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system");
+
+        ModifyRequest request = new ModifyRequest(dn);
+        request.remove("member", "cn=users");
+
+        connection.modify(request);
+
+        Thread.sleep(2000);
+
+        failedACLs = map.getReadACLs(new ActiveMQQueue("TEST.FOO"));
+        assertEquals("set size: " + failedACLs, 1, failedACLs.size());
+
+        connection.close();
+    }
+
+}
+

Added: activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPSecurityTest.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPSecurityTest.java?rev=1147073&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPSecurityTest.java (added)
+++ activemq/trunk/activemq-core/src/test/java/org/apache/activemq/security/CachedLDAPSecurityTest.java Fri Jul 15 10:13:08 2011
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.activemq.security;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.broker.BrokerFactory;
+import org.apache.activemq.broker.BrokerService;
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ApplyLdifFiles;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.apache.directory.server.ldap.LdapServer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.jms.*;
+
+import static org.junit.Assert.assertNotNull;
+
+
+@RunWith( FrameworkRunner.class )
+@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP")})
+@ApplyLdifFiles(
+        "org/apache/activemq/security/activemq-apacheds.ldif"
+)
+public class CachedLDAPSecurityTest extends AbstractLdapTestUnit {
+
+    public BrokerService broker;
+
+    public static LdapServer ldapServer;
+
+    @Before
+    public void setup() throws Exception {
+       broker = BrokerFactory.createBroker("xbean:org/apache/activemq/security/activemq-apacheds.xml");
+       broker.start();
+       broker.waitUntilStarted();
+       //System.in.read();
+    }
+
+    @After
+    public void shutdown() throws Exception {
+        broker.stop();
+        broker.waitUntilStopped();
+    }
+
+    @Test
+    public void testSendReceive() throws Exception {
+        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
+        Connection conn = factory.createQueueConnection("jdoe", "sunflower");
+        Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        conn.start();
+        Queue queue = sess.createQueue("TEST.FOO");
+
+        MessageProducer producer = sess.createProducer(queue);
+        MessageConsumer consumer = sess.createConsumer(queue);
+
+        producer.send(sess.createTextMessage("test"));
+        Message msg = consumer.receive(1000);
+        assertNotNull(msg);
+    }
+
+    @Test
+    public void testTempDestinations() throws Exception {
+        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
+        Connection conn = factory.createQueueConnection("jdoe", "sunflower");
+        Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        conn.start();
+        Queue queue = sess.createTemporaryQueue();
+
+        MessageProducer producer = sess.createProducer(queue);
+        MessageConsumer consumer = sess.createConsumer(queue);
+
+        producer.send(sess.createTextMessage("test"));
+        Message msg = consumer.receive(1000);
+        assertNotNull(msg);
+    }
+
+}
+
+

Added: activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.ldif
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.ldif?rev=1147073&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.ldif (added)
+++ activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.ldif Fri Jul 15 10:13:08 2011
@@ -0,0 +1,270 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You 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.
+## ---------------------------------------------------------------------------
+
+
+##########################
+## Define basic objects ##
+##########################
+
+# Uncomment if adding to open ldap
+# dn: ou=system
+# objectclass: organizationalUnit
+# objectclass: top
+# ou: system
+
+dn: ou=ActiveMQ,ou=system
+objectClass: organizationalUnit
+objectClass: top
+ou: ActiveMQ
+
+dn: ou=Services,ou=system
+ou: Services
+objectClass: organizationalUnit
+objectClass: top
+
+dn: cn=mqbroker,ou=Services,ou=system
+cn: mqbroker
+objectClass: organizationalRole
+objectClass: top
+objectClass: simpleSecurityObject
+userPassword: {SSHA}YvMAkkd66cDecNoejo8jnw5uUUBziyl0
+description: Bind user for MQ broker
+
+
+###################
+## Define groups ##
+###################
+
+
+dn: ou=Group,ou=ActiveMQ,ou=system
+objectClass: organizationalUnit
+objectClass: top
+ou: Group
+
+dn: cn=admins,ou=Group,ou=ActiveMQ,ou=system
+cn: admins
+member: uid=admin
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=users,ou=Group,ou=ActiveMQ,ou=system
+cn: users
+member: uid=jdoe
+objectClass: groupOfNames
+objectClass: top
+
+
+##################
+## Define users ##
+##################
+
+
+dn: ou=User,ou=ActiveMQ,ou=system
+objectClass: organizationalUnit
+objectClass: top
+ou: User
+
+dn: uid=admin,ou=User,ou=ActiveMQ,ou=system
+uid: admin
+userPassword: {SSHA}YvMAkkd66cDecNoejo8jnw5uUUBziyl0
+objectClass: account
+objectClass: simpleSecurityObject
+objectClass: top
+
+
+dn: uid=jdoe,ou=User,ou=ActiveMQ,ou=system
+uid: jdoe
+userPassword: {SSHA}YvMAkkd66cDecNoejo8jnw5uUUBziyl0
+objectclass: inetOrgPerson
+objectclass: organizationalPerson
+objectclass: person
+objectclass: top
+cn: Jane Doe
+sn: Doe
+
+
+#########################
+## Define destinations ##
+#########################
+
+dn: ou=Destination,ou=ActiveMQ,ou=system
+objectClass: organizationalUnit
+objectClass: top
+ou: Destination
+
+dn: ou=Topic,ou=Destination,ou=ActiveMQ,ou=system
+objectClass: organizationalUnit
+objectClass: top
+ou: Topic
+
+dn: ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+objectClass: organizationalUnit
+objectClass: top
+ou: Queue
+
+## TEST.FOO
+
+dn: cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: TEST.FOO
+description: A queue
+objectClass: applicationProcess
+objectClass: top
+
+dn: cn=admin,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: admin
+description: Admin privilege group, members are roles
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=read,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: read
+member: cn=users
+member: cn=admins
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: write
+objectClass: groupOfNames
+objectClass: top
+member: cn=users
+member: cn=admins
+
+
+## FOO.>
+
+dn: cn=FOO.$,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: FOO.$
+description: A queue
+objectClass: applicationProcess
+objectClass: top
+
+dn: cn=admin,cn=FOO.$,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: admin
+description: Admin privilege group, members are roles
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=read,cn=FOO.$,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: read
+member: cn=users
+member: cn=admins
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,cn=FOO.$,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: write
+objectClass: groupOfNames
+objectClass: top
+member: cn=users
+member: cn=admins
+
+
+## BAR.*
+
+dn: cn=BAR.*,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: BAR.*
+description: A queue
+objectClass: applicationProcess
+objectClass: top
+
+dn: cn=admin,cn=BAR.*,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: admin
+description: Admin privilege group, members are roles
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=read,cn=BAR.*,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: read
+member: cn=users
+member: cn=admins
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,cn=BAR.*,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: write
+objectClass: groupOfNames
+objectClass: top
+member: cn=users
+member: cn=admins
+
+#######################
+## Define advisories ##
+#######################
+
+dn: cn=ActiveMQ.Advisory.$,ou=Topic,ou=Destination,ou=ActiveMQ,ou=system
+cn: ActiveMQ.Advisory.$
+objectClass: applicationProcess
+objectClass: top
+description: Advisory topics
+
+dn: cn=read,cn=ActiveMQ.Advisory.$,ou=Topic,ou=Destination,ou=ActiveMQ,ou=system
+cn: read
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,cn=ActiveMQ.Advisory.$,ou=Topic,ou=Destination,ou=ActiveMQ,ou=system
+cn: write
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=admin,cn=ActiveMQ.Advisory.$,ou=Topic,ou=Destination,ou=ActiveMQ,ou=system
+cn: admin
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+######################
+## Define temporary ##
+######################
+
+dn: ou=Temp,ou=Destination,ou=ActiveMQ,ou=system
+objectClass: organizationalUnit
+objectClass: top
+ou: Temp
+
+dn: cn=read,ou=Temp,ou=Destination,ou=ActiveMQ,ou=system
+cn: read
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,ou=Temp,ou=Destination,ou=ActiveMQ,ou=system
+cn: write
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=admin,ou=Temp,ou=Destination,ou=ActiveMQ,ou=system
+cn: admin
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
\ No newline at end of file

Added: activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.xml
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.xml?rev=1147073&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.xml (added)
+++ activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-apacheds.xml Fri Jul 15 10:13:08 2011
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+-->
+<!-- START SNIPPET: xbean -->
+<beans
+  xmlns="http://www.springframework.org/schema/beans"
+  xmlns:amq="http://activemq.apache.org/schema/core"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
+
+  <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
+
+  <broker useJmx="false"  xmlns="http://activemq.apache.org/schema/core" persistent="false">
+
+      <plugins>
+		<simpleAuthenticationPlugin>
+			<users>
+				<authenticationUser username="jdoe" password="sunflower"
+					groups="users"/>
+				<authenticationUser username="admin" password="sunflower"
+					groups="admin"/>
+			</users>
+		</simpleAuthenticationPlugin>
+
+          <authorizationPlugin>
+              <map>
+                  <bean id="CachedLDAPAuthorizationMap" class="org.apache.activemq.security.CachedLDAPAuthorizationMap"
+                        xmlns="http://www.springframework.org/schema/beans">
+                  </bean>
+              </map>
+          </authorizationPlugin>
+      </plugins>
+
+
+    <transportConnectors>
+      <transportConnector uri="tcp://localhost:61616"/>
+    </transportConnectors>
+
+  </broker>
+
+</beans>
+<!-- END SNIPPET: xbean -->

Added: activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.ldif
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.ldif?rev=1147073&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.ldif (added)
+++ activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.ldif Fri Jul 15 10:13:08 2011
@@ -0,0 +1,270 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You 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.
+## ---------------------------------------------------------------------------
+
+
+##########################
+## Define basic objects ##
+##########################
+
+# Uncomment if adding to open ldap
+dn: dc=activemq,dc=apache,dc=org
+dc: activemq
+objectClass: domain
+objectClass: top
+
+dn: ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: ActiveMQ
+
+dn: ou=Services,dc=activemq,dc=apache,dc=org
+ou: Services
+objectClass: organizationalUnit
+objectClass: top
+
+dn: cn=mqbroker,ou=Services,dc=activemq,dc=apache,dc=org
+cn: mqbroker
+objectClass: organizationalRole
+objectClass: top
+objectClass: simpleSecurityObject
+userPassword: {SSHA}YvMAkkd66cDecNoejo8jnw5uUUBziyl0
+description: Bind user for MQ broker
+
+
+###################
+## Define groups ##
+###################
+
+
+dn: ou=Group,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: Group
+
+dn: cn=admins,ou=Group,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: admins
+member: uid=admin
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=users,ou=Group,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: users
+member: uid=jdoe
+objectClass: groupOfNames
+objectClass: top
+
+
+##################
+## Define users ##
+##################
+
+
+dn: ou=User,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: User
+
+dn: uid=admin,ou=User,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+uid: admin
+userPassword: {SSHA}YvMAkkd66cDecNoejo8jnw5uUUBziyl0
+objectClass: account
+objectClass: simpleSecurityObject
+objectClass: top
+
+
+dn: uid=jdoe,ou=User,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+uid: jdoe
+userPassword: {SSHA}YvMAkkd66cDecNoejo8jnw5uUUBziyl0
+objectclass: inetOrgPerson
+objectclass: organizationalPerson
+objectclass: person
+objectclass: top
+cn: Jane Doe
+sn: Doe
+
+
+#########################
+## Define destinations ##
+#########################
+
+dn: ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: Destination
+
+dn: ou=Topic,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: Topic
+
+dn: ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: Queue
+
+## TEST.FOO
+
+dn: cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: TEST.FOO
+description: A queue
+objectClass: applicationProcess
+objectClass: top
+
+dn: cn=admin,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: admin
+description: Admin privilege group, members are roles
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=read,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: read
+member: cn=users
+member: cn=admins
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: write
+objectClass: groupOfNames
+objectClass: top
+member: cn=users
+member: cn=admins
+
+
+## FOO.>
+
+dn: cn=FOO.$,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: FOO.$
+description: A queue
+objectClass: applicationProcess
+objectClass: top
+
+dn: cn=admin,cn=FOO.$,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: admin
+description: Admin privilege group, members are roles
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=read,cn=FOO.$,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: read
+member: cn=users
+member: cn=admins
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,cn=FOO.$,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: write
+objectClass: groupOfNames
+objectClass: top
+member: cn=users
+member: cn=admins
+
+
+## BAR.*
+
+dn: cn=BAR.*,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: BAR.*
+description: A queue
+objectClass: applicationProcess
+objectClass: top
+
+dn: cn=admin,cn=BAR.*,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: admin
+description: Admin privilege group, members are roles
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=read,cn=BAR.*,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: read
+member: cn=users
+member: cn=admins
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,cn=BAR.*,ou=Queue,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: write
+objectClass: groupOfNames
+objectClass: top
+member: cn=users
+member: cn=admins
+
+#######################
+## Define advisories ##
+#######################
+
+dn: cn=ActiveMQ.Advisory.$,ou=Topic,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: ActiveMQ.Advisory.$
+objectClass: applicationProcess
+objectClass: top
+description: Advisory topics
+
+dn: cn=read,cn=ActiveMQ.Advisory.$,ou=Topic,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: read
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,cn=ActiveMQ.Advisory.$,ou=Topic,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: write
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=admin,cn=ActiveMQ.Advisory.$,ou=Topic,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: admin
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+######################
+## Define temporary ##
+######################
+
+dn: ou=Temp,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+objectClass: organizationalUnit
+objectClass: top
+ou: Temp
+
+dn: cn=read,ou=Temp,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: read
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,ou=Temp,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: write
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=admin,ou=Temp,ou=Destination,ou=ActiveMQ,dc=activemq,dc=apache,dc=org
+cn: admin
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
\ No newline at end of file

Added: activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.xml
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.xml?rev=1147073&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.xml (added)
+++ activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/activemq-openldap.xml Fri Jul 15 10:13:08 2011
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+-->
+<!-- START SNIPPET: xbean -->
+<beans
+  xmlns="http://www.springframework.org/schema/beans"
+  xmlns:amq="http://activemq.apache.org/schema/core"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
+
+  <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
+
+  <broker useJmx="false"  xmlns="http://activemq.apache.org/schema/core" persistent="false">
+
+      <plugins>
+		<simpleAuthenticationPlugin>
+			<users>
+				<authenticationUser username="jdoe" password="sunflower"
+					groups="users"/>
+				<authenticationUser username="admin" password="sunflower"
+					groups="admin"/>
+			</users>
+		</simpleAuthenticationPlugin>
+
+          <authorizationPlugin>
+              <map>
+                  <bean id="CachedLDAPAuthorizationMap" class="org.apache.activemq.security.CachedLDAPAuthorizationMap"
+                        xmlns="http://www.springframework.org/schema/beans">
+                      <property name="connectionURL" value="ldap://localhost:389" />
+                      <property name="connectionUsername" value="cn=admin,dc=activemq,dc=apache,dc=org" />
+                      <property name="connectionPassword" value="sunflower" />
+                      <property name="baseDn" value="dc=activemq,dc=apache,dc=org" />
+                      <property name="refreshInterval" value="300000" /> <!-- refresh every 5 min -->
+                  </bean>
+              </map>
+          </authorizationPlugin>
+      </plugins>
+
+
+    <transportConnectors>
+      <transportConnector uri="tcp://localhost:61616"/>
+    </transportConnectors>
+
+  </broker>
+
+</beans>
+<!-- END SNIPPET: xbean -->

Added: activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/add.ldif
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/add.ldif?rev=1147073&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/add.ldif (added)
+++ activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/add.ldif Fri Jul 15 10:13:08 2011
@@ -0,0 +1,47 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You 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.
+## ---------------------------------------------------------------------------
+
+
+## FAILED
+
+dn: cn=FAILED,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: FAILED
+description: New queue
+objectClass: applicationProcess
+objectClass: top
+
+dn: cn=admin,cn=FAILED,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: admin
+description: Admin privilege group, members are roles
+member: cn=admins
+member: cn=users
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=read,cn=FAILED,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: read
+member: cn=users
+member: cn=admins
+objectClass: groupOfNames
+objectClass: top
+
+dn: cn=write,cn=FAILED,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+cn: write
+objectClass: groupOfNames
+objectClass: top
+member: cn=users
+member: cn=admins
\ No newline at end of file

Added: activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/delete.ldif
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/delete.ldif?rev=1147073&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/delete.ldif (added)
+++ activemq/trunk/activemq-core/src/test/resources/org/apache/activemq/security/delete.ldif Fri Jul 15 10:13:08 2011
@@ -0,0 +1,28 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements.  See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You 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.
+## ---------------------------------------------------------------------------
+
+dn: cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+changetype: delete
+
+dn: cn=admin,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+changetype: delete
+
+dn: cn=read,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+changetype: delete
+
+dn: cn=write,cn=TEST.FOO,ou=Queue,ou=Destination,ou=ActiveMQ,ou=system
+changetype: delete
\ No newline at end of file