[jboss-cvs] JBossAS SVN: r79030 - in projects/naming/trunk/jnpserver/src: main/java/org/jnp/server and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Oct 2 10:43:05 EDT 2008


Author: scott.stark at jboss.org
Date: 2008-10-02 10:43:05 -0400 (Thu, 02 Oct 2008)
New Revision: 79030

Added:
   projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/JndiPermission.java
   projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/JndiPermissionUnitTest.java
   projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/NamingServerSecurityManagerUnitTest.java
   projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/QueueSecurityManager.java
   projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/TestSecurityManager.java
Modified:
   projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/LocalOnlyContextFactory.java
   projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/NamingContext.java
   projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/EventMgr.java
   projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/NamingBeanImpl.java
   projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/NamingServer.java
Log:
JBNAME-8, add support for permissions when running under a security manager

Modified: projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/LocalOnlyContextFactory.java
===================================================================
--- projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/LocalOnlyContextFactory.java	2008-10-02 14:42:57 UTC (rev 79029)
+++ projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/LocalOnlyContextFactory.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -43,9 +43,10 @@
          public Context getInitialContext(Hashtable env)
            throws NamingException
          {
-             if (NamingContext.localServer == null)
+            Naming localServer = NamingContext.getLocal();
+             if (localServer == null)
                 throw new NamingException("Local server is not initialized");
-             return new NamingContext(env, null, NamingContext.localServer);
+             return new NamingContext(env, null, localServer);
          }
 
         // ObjectFactory implementation ----------------------------------

Modified: projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/NamingContext.java
===================================================================
--- projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/NamingContext.java	2008-10-02 14:42:57 UTC (rev 79029)
+++ projects/naming/trunk/jnpserver/src/main/java/org/jnp/interfaces/NamingContext.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -162,25 +162,43 @@
    private static Logger log = Logger.getLogger(NamingContext.class);
 
    // Static --------------------------------------------------------
-   
-   public static Hashtable haServers = new Hashtable();
-
+   /** HAJNDI keyed by partition name */
+   private static Hashtable haServers = new Hashtable();
+   private static RuntimePermission GET_HA_NAMING_SERVER = new RuntimePermission("org.jboss.naming.NamingContext.getHANamingServerForPartition");
+   private static RuntimePermission SET_HA_NAMING_SERVER = new RuntimePermission("org.jboss.naming.NamingContext.setHANamingServerForPartition");
    public static void setHANamingServerForPartition(String partitionName, Naming haServer)
    {
+      SecurityManager security = System.getSecurityManager();
+      if(security != null)
+         security.checkPermission(SET_HA_NAMING_SERVER);
       haServers.put(partitionName, haServer);
    }
 
    public static void removeHANamingServerForPartition(String partitionName)
    {
+      SecurityManager security = System.getSecurityManager();
+      if(security != null)
+         security.checkPermission(SET_HA_NAMING_SERVER);
       haServers.remove(partitionName);
    }
 
    public static Naming getHANamingServerForPartition(String partitionName)
    {
+      SecurityManager security = System.getSecurityManager();
+      if(security != null)
+         security.checkPermission(GET_HA_NAMING_SERVER);
       return (Naming) haServers.get(partitionName);
    }
 
-   public static Naming localServer;
+   /**
+    * The jvm local server used for non-transport access to the naming
+    * server
+    * @see #checkRef(Hashtable)
+    * @see {@linkplain LocalOnlyContextFactory}
+    */
+   private static Naming localServer;
+   private static RuntimePermission GET_LOCAL_SERVER = new RuntimePermission("org.jboss.naming.NamingContext.getLocal");
+   private static RuntimePermission SET_LOCAL_SERVER = new RuntimePermission("org.jboss.naming.NamingContext.setLocal");
 
    // Attributes ----------------------------------------------------
    Naming naming;
@@ -442,12 +460,18 @@
       return serverInfo;
    }
 
-   public Naming getLocal()
+   public static Naming getLocal()
    {
+      SecurityManager security = System.getSecurityManager();
+      if(security != null)
+         security.checkPermission(GET_LOCAL_SERVER);
       return localServer;
    }
    public static void setLocal(Naming server)
    {
+      SecurityManager security = System.getSecurityManager();
+      if(security != null)
+         security.checkPermission(SET_LOCAL_SERVER);
       localServer = server;
    }
 

Modified: projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/EventMgr.java
===================================================================
--- projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/EventMgr.java	2008-10-02 14:42:57 UTC (rev 79029)
+++ projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/EventMgr.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -27,11 +27,29 @@
 import javax.naming.Name;
 
 /**
+ * A plugin for the manager which dispatches EventContext events to listeners 
+ * 
+ * @see {@linkplain ExecutorEventMgr}
  * @author Scott.Stark at jboss.org
  * @version $Revision:$
  */
 public interface EventMgr
 {
+   /**
+    * Dispatch an event to the listeners.
+    * 
+    * @param fullName - the full path of name of the event location
+    * @param oldb - the possibly old binding of the event
+    * @param newb - the possibly new binding of the event
+    * @param type - one of {@link javax.naming.event.NamingEvent#OBJECT_ADDED},
+    * {@link javax.naming.event.NamingEvent#OBJECT_CHANGED},
+    * {@link javax.naming.event.NamingEvent#OBJECT_REMOVED} events.
+    * @param changeInfo - the provider specific change information. The current
+    * impl passes in the name of the operation that generated the event.
+    * @param listeners - the list of NamingListener info for the EventContext
+    * associated with the event.
+    * @param scopes - a set of the EventContext scopes that apply.
+    */
    void fireEvent(Name fullName, Binding oldb, Binding newb, int type,
          String changeInfo, EventListeners listeners, Set<Integer> scopes);
 }

Added: projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/JndiPermission.java
===================================================================
--- projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/JndiPermission.java	                        (rev 0)
+++ projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/JndiPermission.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -0,0 +1,792 @@
+/*
+ * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jnp.server;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.io.ObjectOutputStream;
+import java.io.ObjectInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+import javax.naming.Name;
+
+/**
+ * This class represents access to a path in the JNDI tree. A JndiPermission
+ * consists of a pathname and a set of actions valid for that pathname.
+ * <P>
+ * Pathname is the pathname of the file or directory granted the specified
+ * actions. A pathname that ends in "/*" indicates all the files and directories
+ * contained in that directory. A pathname that ends with "/-" indicates
+ * (recursively) all files and subdirectories contained in that directory. A
+ * pathname consisting of the special token "&lt;&lt;ALL BINDINGS&gt;&gt;" matches
+ * <b>any</b> file.
+ * <P>
+ * The actions to be granted are passed to the constructor in a string
+ * containing a list of one or more comma-separated keywords. The possible
+ * keywords are "bind", "rebind", "unbind", "lookup", "list", "listBindings",
+ * and "createSubcontext". Their meaning is defined as follows:
+ * <P>
+ * <DL>
+ * <DT> bind
+ * <DD> Context.bind permission
+ * <DT> rebind
+ * <DD> Context.rebind permission
+ * <DT> unbind
+ * <DD> Context.unbind permission.
+ * <DT> lookup
+ * <DD> Context.lookup permission.
+ * <DT> list
+ * <DD> Context.list permission.
+ * <DT> listBindings
+ * <DD> Context.listBindings permission.
+ * <DT> createSubcontext
+ * <DD> Context.createSubcontext permission.
+ * </DL>
+ * <P>
+ * The actions string is converted to lowercase before processing.
+ * <P>
+ * Be careful when granting JndiPermissions. Think about the implications of
+ * granting read and especially write access to various files and directories.
+ * The "&lt;&lt;ALL BINDINGS>>" permission with write action is especially
+ * dangerous. This grants permission to write to the entire file system. One
+ * thing this effectively allows is replacement of the system binary, including
+ * the JVM runtime environment.
+ * 
+ * <p>
+ * Please note: Code can always read a file from the same directory it's in (or
+ * a subdirectory of that directory); it does not need explicit permission to do
+ * so.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ * 
+ * 
+ * @author Marianne Mueller
+ * @author Roland Schemers
+ * @author Scott.Stark at jboss.org
+ * 
+ * @serial exclude
+ * @version $Revision$
+ */
+public final class JndiPermission extends Permission
+   implements Serializable
+{
+   private static final long serialVersionUID = 1;
+
+   /**
+    * bind action.
+    */
+   public final static int BIND = 1;
+   /**
+    * rebind action.
+    */
+   public final static int REBIND = 2;
+   /**
+    * unbind action.
+    */
+   public final static int UNBIND = 4;
+   /**
+    * lookup action.
+    */
+   public final static int LOOKUP = 8;
+   /**
+    * list action.
+    */
+   public final static int LIST = 16;
+
+   public final static int LIST_BINDINGS = 32;
+
+   public final static int CREATE_SUBCONTEXT = 64;
+   private final static int ACTION_COUNT = 7;
+
+
+   /**
+    * All actions (bind, rebind, unbind, lookup, list, listBindings, createSubcontext)
+    */
+   public final static int ALL = LOOKUP | REBIND | BIND | UNBIND | LIST
+         | LIST_BINDINGS | CREATE_SUBCONTEXT;
+
+   /**
+    * No actions.
+    */
+   public final static int NONE = 0x0;
+
+   public static final String BIND_ACTION = "bind";
+
+   public static final String REBIND_ACTION = "rebind";
+
+   public static final String UNBIND_ACTION = "unbind";
+
+   public static final String LOOKUP_ACTION = "lookup";
+
+   public static final String LIST_ACTION = "list";
+
+   public static final String LIST_BINDINGS_ACTION = "listBindings";
+   public static final String ALL_ACTION = "*";
+
+   public static final String CREATE_SUBCONTEXT_ACTION = "createSubcontext";
+   private static final String[] ALL_ACTIONS = {BIND_ACTION, REBIND_ACTION, UNBIND_ACTION,
+      LOOKUP_ACTION, LIST_ACTION, LIST_BINDINGS_ACTION, CREATE_SUBCONTEXT_ACTION
+   };
+   private static final HashMap<String, Integer> actionMap = new HashMap<String, Integer>();
+   static
+   {
+      actionMap.put(BIND_ACTION, BIND);
+      actionMap.put(REBIND_ACTION, REBIND);
+      actionMap.put(UNBIND_ACTION, UNBIND);
+      actionMap.put(LOOKUP_ACTION, LOOKUP);
+      actionMap.put(LIST_ACTION, LIST);
+      actionMap.put(LIST_BINDINGS_ACTION.toLowerCase(), LIST_BINDINGS);
+      actionMap.put(CREATE_SUBCONTEXT_ACTION.toLowerCase(), CREATE_SUBCONTEXT);
+      actionMap.put(ALL_ACTION, ALL);
+   }
+
+   // the actions mask
+   private transient int mask;
+
+   // does path indicate a directory? (wildcard or recursive)
+   private transient boolean directory;
+
+   // is it a recursive directory specification?
+   private transient boolean recursive;
+
+   /**
+    * the actions string.
+    * 
+    * @serial
+    */
+   private String actions; // Left null as long as possible, then
+
+   // created and re-used in the getAction function.
+
+   // canonicalized dir path. In the case of
+   // directories, it is the name "/blah/*" or "/blah/-" without
+   // the last character (the "*" or "-").
+
+   private transient String cpath;
+
+   // static Strings used by init(int mask)
+   private static final char RECURSIVE_CHAR = '-';
+
+   private static final char WILD_CHAR = '*';
+
+   /**
+    * initialize a JndiPermission object. Common to all constructors. Also
+    * called during de-serialization.
+    * 
+    * @param mask
+    *           the actions mask to use.
+    * 
+    */
+   private void init(int mask)
+   {
+      if ((mask & ALL) != mask)
+         throw new IllegalArgumentException("invalid actions mask");
+
+      if (mask == NONE)
+         throw new IllegalArgumentException("invalid actions mask");
+
+      if ((cpath = getName()) == null)
+         throw new NullPointerException("name can't be null");
+
+      this.mask = mask;
+
+      if (cpath.equals("<<ALL BINDINGS>>"))
+      {
+         directory = true;
+         recursive = true;
+         cpath = "";
+         return;
+      }
+
+      int len = cpath.length();
+      char last = ((len > 0) ? cpath.charAt(len - 1) : 0);
+
+      if (last == RECURSIVE_CHAR && cpath.charAt(len - 2) == '/')
+      {
+         directory = true;
+         recursive = true;
+         cpath = cpath.substring(0, --len);
+      }
+      else if (last == WILD_CHAR && cpath.charAt(len - 2) == '/')
+      {
+         directory = true;
+         // recursive = false;
+         cpath = cpath.substring(0, --len);
+      }
+      else
+      {
+         // overkill since they are initialized to false, but
+         // commented out here to remind us...
+         // directory = false;
+         // recursive = false;
+      }
+   }
+
+   /**
+    * Creates a new JndiPermission object with the specified actions. <i>path</i>
+    * is the pathname of a file or directory, and <i>actions</i> contains a
+    * comma-separated list of the desired actions granted on the file or
+    * directory. Possible actions are "bind", "rebind", "unbind", "lookup",
+    * "list", "listBindings", and "createSubcontext".
+    * 
+    * <p>
+    * A pathname that ends in "/*" (where "/" is the file separator character,
+    * <code>'/'</code>) indicates all the files and directories contained in
+    * that directory. A pathname that ends with "/-" indicates (recursively) all
+    * files and subdirectories contained in that directory. The special pathname
+    * "&lt;&lt;ALL BINDINGS&gt;&gt;" matches any file.
+    * 
+    * <p>
+    * A pathname consisting of a single "*" indicates all the files in the
+    * current directory, while a pathname consisting of a single "-" indicates
+    * all the files in the current directory and (recursively) all files and
+    * subdirectories contained in the current directory.
+    * 
+    * <p>
+    * A pathname containing an empty string represents an empty path.
+    * 
+    * @param path
+    *           the pathname of the file/directory.
+    * @param actions
+    *           the action string.
+    * 
+    * @throws IllegalArgumentException
+    *            If actions is <code>null</code>, empty or contains an action
+    *            other than the specified possible actions.
+    */
+
+   public JndiPermission(String path, String actions)
+   {
+      super(path);
+      init(getMask(actions));
+   }
+   public JndiPermission(Name path, String actions)
+   {
+      super(path.toString());
+      init(getMask(actions));
+   }
+
+   /**
+    * Creates a new JndiPermission object using an action mask. More efficient
+    * than the JndiPermission(String, String) constructor. Can be used from
+    * within code that needs to create a JndiPermission object to pass into the
+    * <code>implies</code> method.
+    * 
+    * @param path
+    *           the pathname of the file/directory.
+    * @param mask
+    *           the action mask to use.
+    */
+
+   // package private for use by the JndiPermissionCollection add method
+   JndiPermission(String path, int mask)
+   {
+      super(path);
+      init(mask);
+   }
+   public JndiPermission(Name path, int mask)
+   {
+      super(path.toString());
+      init(mask);
+   }
+
+   /**
+    * Checks if this JndiPermission object "implies" the specified permission.
+    * <P>
+    * More specifically, this method returns true if:
+    * <p>
+    * <ul>
+    * <li> <i>p</i> is an instanceof JndiPermission,
+    * <p>
+    * <li> <i>p</i>'s actions are a proper subset of this object's actions, and
+    * <p>
+    * <li> <i>p</i>'s pathname is implied by this object's pathname. For
+    * example, "/tmp/*" implies "/tmp/foo", since "/tmp/*" encompasses all files
+    * in the "/tmp" directory, including the one named "foo".
+    * </ul>
+    * 
+    * @param p
+    *           the permission to check against.
+    * 
+    * @return <code>true</code> if the specified permission is not
+    *         <code>null</code> and is implied by this object,
+    *         <code>false</code> otherwise.
+    */
+   public boolean implies(Permission p)
+   {
+      if (!(p instanceof JndiPermission))
+         return false;
+
+      JndiPermission that = (JndiPermission) p;
+
+      // we get the effective mask. i.e., the "and" of this and that.
+      // They must be equal to that.mask for implies to return true.
+
+      return ((this.mask & that.mask) == that.mask) && impliesIgnoreMask(that);
+   }
+
+   /**
+    * Checks if the Permission's actions are a proper subset of the this
+    * object's actions. Returns the effective mask iff the this JndiPermission's
+    * path also implies that JndiPermission's path.
+    * 
+    * @param that
+    *           the JndiPermission to check against.
+    * @param exact
+    *           return immediately if the masks are not equal
+    * @return the effective mask
+    */
+   boolean impliesIgnoreMask(JndiPermission that)
+   {
+      if (this.directory)
+      {
+         if (this.recursive)
+         {
+            // make sure that.path is longer then path so
+            // something like /foo/- does not imply /foo
+            if (that.directory)
+            {
+               return (that.cpath.length() >= this.cpath.length())
+                     && that.cpath.startsWith(this.cpath);
+            }
+            else
+            {
+               return ((that.cpath.length() >= this.cpath.length()) && that.cpath
+                     .startsWith(this.cpath));
+            }
+         }
+         else
+         {
+            if (that.directory)
+            {
+               // if the permission passed in is a directory
+               // specification, make sure that a non-recursive
+               // permission (i.e., this object) can't imply a recursive
+               // permission.
+               if (that.recursive)
+                  return false;
+               else
+                  return (this.cpath.equals(that.cpath));
+            }
+            else
+            {
+               int last = that.cpath.lastIndexOf('/');
+               if (last == -1)
+                  return false;
+               else
+               {
+                  // this.cpath.equals(that.cpath.substring(0, last+1));
+                  // Use regionMatches to avoid creating new string
+                  return (this.cpath.length() == (last + 1))
+                        && this.cpath.regionMatches(0, that.cpath, 0, last + 1);
+               }
+            }
+         }
+      }
+      else if (that.directory)
+      {
+         // if this is NOT recursive/wildcarded,
+         // do not let it imply a recursive/wildcarded permission
+         return false;
+      }
+      else
+      {
+         return (this.cpath.equals(that.cpath));
+      }
+   }
+
+   /**
+    * Checks two JndiPermission objects for equality. Checks that <i>obj</i> is
+    * a JndiPermission, and has the same pathname and actions as this object.
+    * <P>
+    * 
+    * @param obj
+    *           the object we are testing for equality with this object.
+    * @return <code>true</code> if obj is a JndiPermission, and has the same
+    *         pathname and actions as this JndiPermission object,
+    *         <code>false</code> otherwise.
+    */
+   public boolean equals(Object obj)
+   {
+      if (obj == this)
+         return true;
+
+      if (!(obj instanceof JndiPermission))
+         return false;
+
+      JndiPermission that = (JndiPermission) obj;
+
+      return (this.mask == that.mask) && this.cpath.equals(that.cpath)
+            && (this.directory == that.directory)
+            && (this.recursive == that.recursive);
+   }
+
+   /**
+    * Returns the hash code value for this object.
+    * 
+    * @return a hash code value for this object.
+    */
+
+   public int hashCode()
+   {
+      return this.cpath.hashCode();
+   }
+
+   
+   /**
+    * Converts an actions String to an actions mask.
+    * 
+    * @param action - the comma separated list of actions.
+    * @return the actions mask.
+    */
+   private static int getMask(String actions)
+   {
+
+      int mask = NONE;
+
+      // Null action valid?
+      if (actions == null || actions.length() == 0)
+      {
+         return mask;
+      }
+      // Check against use of constants
+      if (actions == LOOKUP_ACTION)
+      {
+         return LOOKUP;
+      }
+      else if (actions == REBIND_ACTION)
+      {
+         return REBIND;
+      }
+      else if (actions == BIND_ACTION)
+      {
+         return BIND;
+      }
+      else if (actions == UNBIND_ACTION)
+      {
+         return UNBIND;
+      }
+      else if (actions == LIST_ACTION)
+      {
+         return LIST;
+      }
+      else if (actions == LIST_BINDINGS_ACTION)
+      {
+         return LIST_BINDINGS;
+      }
+      else if (actions == CREATE_SUBCONTEXT_ACTION)
+      {
+         return CREATE_SUBCONTEXT;
+      }
+
+      String[] sa = actions.split(",");
+      for(String s : sa)
+      {
+         String key = s.toLowerCase();
+         if(actionMap.containsKey(key) == false)
+         {
+            throw new IllegalArgumentException("invalid permission, unknown action: " + s);
+         }
+         int i = actionMap.get(key);
+         mask |= i;
+      }
+
+      return mask;
+   }
+
+   /**
+    * Return the current action mask. Used by the JndiPermissionCollection.
+    * 
+    * @return the actions mask.
+    */
+
+   int getMask()
+   {
+      return mask;
+   }
+
+   /**
+    * Return the canonical string representation of the actions. Always returns
+    * present actions in the following order: bind, rebind, unbind, lookup,
+    * list, listBindings, createSubcontext
+    * 
+    * @return the canonical string representation of the actions.
+    */
+   private static String getActions(int mask)
+   {
+      StringBuilder sb = new StringBuilder();
+      boolean insertComma = false;
+      for(int n = 0; n < ACTION_COUNT; n ++)
+      {
+         int action = 1 << n;
+         if((mask & action) == action)
+         {
+            if(insertComma)
+               sb.append(',');
+            sb.append(ALL_ACTIONS[n]);
+            insertComma = true;
+         }
+      }
+
+      return sb.toString();
+   }
+
+   /**
+    * Returns the "canonical string representation" of the actions. That is,
+    * this method always returns present actions in the following order: bind,
+    * rebind, unbind, lookup, list, listBindings, createSubcontext.
+    * For example, if this JndiPermission object allows
+    * both unbind and bind actions, a call to <code>getActions</code> will
+    * return the string "bind,unbind".
+    * 
+    * @return the canonical string representation of the actions.
+    */
+   public String getActions()
+   {
+      if (actions == null)
+         actions = getActions(this.mask);
+
+      return actions;
+   }
+
+   /**
+    * Returns a new PermissionCollection object for storing JndiPermission
+    * objects.
+    * <p>
+    * JndiPermission objects must be stored in a manner that allows them to be
+    * inserted into the collection in any order, but that also enables the
+    * PermissionCollection <code>implies</code> method to be implemented in an
+    * efficient (and consistent) manner.
+    * 
+    * <p>
+    * For example, if you have two JndiPermissions:
+    * <OL>
+    * <LI> <code>"/tmp/-", "bind"</code>
+    * <LI> <code>"/tmp/scratch/foo", "unbind"</code>
+    * </OL>
+    * 
+    * <p>
+    * and you are calling the <code>implies</code> method with the
+    * JndiPermission:
+    * 
+    * <pre>
+    *   &quot;/tmp/scratch/foo&quot;, &quot;bind,unbind&quot;,
+    * </pre>
+    * 
+    * then the <code>implies</code> function must take into account both the
+    * "/tmp/-" and "/tmp/scratch/foo" permissions, so the effective permission
+    * is "bind,unbind", and <code>implies</code> returns true. The "implies"
+    * semantics for JndiPermissions are handled properly by the
+    * PermissionCollection object returned by this
+    * <code>newPermissionCollection</code> method.
+    * 
+    * @return a new PermissionCollection object suitable for storing
+    *         JndiPermissions.
+    */
+
+   public PermissionCollection newPermissionCollection()
+   {
+      return new JndiPermissionCollection();
+   }
+
+   /**
+    * WriteObject is called to save the state of the JndiPermission to a stream.
+    * The actions are serialized, and the superclass takes care of the name.
+    */
+   private void writeObject(ObjectOutputStream s) throws IOException
+   {
+      // Write out the actions. The superclass takes care of the name
+      // call getActions to make sure actions field is initialized
+      if (actions == null)
+         getActions();
+      s.defaultWriteObject();
+   }
+
+   /**
+    * readObject is called to restore the state of the JndiPermission from a
+    * stream.
+    */
+   private void readObject(ObjectInputStream s) throws IOException,
+         ClassNotFoundException
+   {
+      // Read in the actions, then restore everything else by calling init.
+      s.defaultReadObject();
+      init(getMask(actions));
+   }
+}
+
+/**
+ * A JndiPermissionCollection stores a set of JndiPermission permissions.
+ * JndiPermission objects must be stored in a manner that allows them to be
+ * inserted in any order, but enable the implies function to evaluate the
+ * implies method. For example, if you have two JndiPermissions:
+ * <OL>
+ * <LI> "/tmp/-", "bind"
+ * <LI> "/tmp/scratch/foo", "unbind"
+ * </OL>
+ * And you are calling the implies function with the JndiPermission:
+ * "/tmp/scratch/foo", "bind,unbind", then the implies function must take into
+ * account both the /tmp/- and /tmp/scratch/foo permissions, so the effective
+ * permission is "bind,unbind".
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ * 
+ * 
+ * @author Marianne Mueller
+ * @author Roland Schemers
+ * @author Scott.Stark at jboss.org
+ * 
+ * @serial include
+ * @version $Revision$
+ * 
+ */
+final class JndiPermissionCollection extends PermissionCollection implements
+      Serializable
+{
+   private static final long serialVersionUID = 1;
+   private List<JndiPermission> perms;
+
+   /**
+    * Create an empty JndiPermissions object.
+    * 
+    */
+   public JndiPermissionCollection()
+   {
+      perms = new ArrayList<JndiPermission>();
+   }
+
+   /**
+    * Adds a permission to the JndiPermissions. The key for the hash is
+    * permission.path.
+    * 
+    * @param permission
+    *           the Permission object to add.
+    * 
+    * @exception IllegalArgumentException -
+    *               if the permission is not a JndiPermission
+    * 
+    * @exception SecurityException -
+    *               if this JndiPermissionCollection object has been marked
+    *               readonly
+    */
+
+   public void add(Permission permission)
+   {
+      if (!(permission instanceof JndiPermission))
+         throw new IllegalArgumentException("invalid permission: " + permission);
+      if (isReadOnly())
+         throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
+
+      synchronized (this)
+      {
+         perms.add((JndiPermission)permission);
+      }
+   }
+
+   /**
+    * Check and see if this set of permissions implies the permissions expressed
+    * in "permission".
+    * 
+    * @param p
+    *           the Permission object to compare
+    * 
+    * @return true if "permission" is a proper subset of a permission in the
+    *         set, false if not.
+    */
+
+   public boolean implies(Permission permission)
+   {
+      if (!(permission instanceof JndiPermission))
+         return false;
+
+      JndiPermission fp = (JndiPermission) permission;
+
+      int desired = fp.getMask();
+      int effective = 0;
+      int needed = desired;
+
+      synchronized (this)
+      {
+         for(JndiPermission x : perms)
+         {
+            if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(fp))
+            {
+               effective |= x.getMask();
+               if ((effective & desired) == desired)
+                  return true;
+               needed = (desired ^ effective);
+            }
+         }
+      }
+      return false;
+   }
+
+   /**
+    * Returns an enumeration of all the JndiPermission objects in the container.
+    * 
+    * @return an enumeration of all the JndiPermission objects.
+    */
+
+   public Enumeration elements()
+   {
+      // Convert Iterator into Enumeration
+      synchronized (this)
+      {
+         return Collections.enumeration(perms);
+      }
+   }
+
+}


Property changes on: projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/JndiPermission.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision

Modified: projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/NamingBeanImpl.java
===================================================================
--- projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/NamingBeanImpl.java	2008-10-02 14:42:57 UTC (rev 79029)
+++ projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/NamingBeanImpl.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -21,7 +21,6 @@
  */
 package org.jnp.server;
 
-import java.util.Enumeration;
 import java.util.Hashtable;
 
 import javax.naming.Context;
@@ -40,7 +39,7 @@
  * a refactoring of the legacy org.jnp.server.Main into a 
  * 
  * @author Scott.Stark at jboss.org
- * @version $Revision:$
+ * @version $Revision$
  */
 public class NamingBeanImpl
    implements NamingBean
@@ -53,6 +52,7 @@
    protected boolean InstallGlobalService = true;
    /** A flag indicating if theServer will try to use the NamingContext.setLocal value */
    protected boolean UseGlobalService = true;
+   /** The plugin for the manager which dispatches EventContext events to listeners */
    private EventMgr eventMgr;
 
    // Static --------------------------------------------------------
@@ -122,7 +122,7 @@
       {
          // See if we should try to reuse the current local server
          if( UseGlobalService == true )
-            theServer = NamingContext.localServer;
+            theServer = NamingContext.getLocal();
          // If not, or there is no server create one
          if( theServer == null )
             theServer = createServer();
@@ -146,12 +146,11 @@
       issue a warning as this means JNDI lookups are going through RMI.
       */
       InitialContext iniCtx = new InitialContext();
-      Hashtable env = iniCtx.getEnvironment();
+      Hashtable<?,?> env = iniCtx.getEnvironment();
       log.debug("InitialContext Environment: ");
       Object providerURL = null;
-      for (Enumeration keys = env.keys(); keys.hasMoreElements(); )
+      for (Object key : env.keySet())
       {
-         Object key = keys.nextElement();
          Object value = env.get(key);
          String type = value == null ? "" : value.getClass().getName();
          log.debug("key="+key+", value("+type+")="+value);
@@ -181,7 +180,7 @@
     */
    public void stop()
    {
-      if(NamingContext.localServer == theServer)
+      if(NamingContext.getLocal() == theServer)
          NamingContext.setLocal(null);
    }
 }


Property changes on: projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/NamingBeanImpl.java
___________________________________________________________________
Name: svn:keywords
   - Id,Revision
   + Id Revision

Modified: projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/NamingServer.java
===================================================================
--- projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/NamingServer.java	2008-10-02 14:42:57 UTC (rev 79029)
+++ projects/naming/trunk/jnpserver/src/main/java/org/jnp/server/NamingServer.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -28,7 +28,6 @@
 import java.util.Map;
 import java.util.Vector;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
 import javax.naming.Binding;
 import javax.naming.CannotProceedException;
 import javax.naming.Context;
@@ -75,10 +74,10 @@
    protected NamingParser parser = new NamingParser();
    protected NamingServer parent;
    /** The NamingListeners registered with this context */
-   private EventListeners listeners;
+   private transient EventListeners listeners;
    /** The manager for EventContext listeners */
-   private EventMgr eventMgr;
-   private boolean trace;
+   private transient EventMgr eventMgr;
+   private transient boolean trace;
 
    // Static --------------------------------------------------------
 
@@ -204,11 +203,18 @@
             }
             catch (NameNotFoundException e)
             {
+               Name fullName = (Name) prefix.clone();
+               fullName.addAll(name);
+               SecurityManager sm = System.getSecurityManager();
+               if(sm != null)
+               {
+                  JndiPermission perm = new JndiPermission(fullName, JndiPermission.BIND);
+                  sm.checkPermission(perm);
+               }
+
                Binding newb = setBinding(name,obj,className);
                // Notify event listeners
                Binding oldb = null;
-               Name fullName = (Name) prefix.clone();
-               fullName.addAll(name);
                this.fireEvent(fullName, oldb, newb, NamingEvent.OBJECT_ADDED, "bind");
             }
          }
@@ -262,7 +268,16 @@
          }
          else
          {
+            SecurityManager sm = System.getSecurityManager();
+            Name fullName = (Name) prefix.clone();
             String comp = name.get(0);
+            fullName.add(comp);
+            if(sm != null)
+            {
+               JndiPermission perm = new JndiPermission(fullName, JndiPermission.REBIND);
+               sm.checkPermission(perm);
+            }
+            
             Binding oldb = table.get(comp);
             Binding newb = setBinding(name,obj,className);
             // Notify event listeners
@@ -271,8 +286,6 @@
                int type = NamingEvent.OBJECT_CHANGED;
                if(oldb == null)
                   type = NamingEvent.OBJECT_ADDED;
-               Name fullName = (Name) prefix.clone();
-               fullName.add(comp);
                this.fireEvent(fullName, oldb, newb, type, "rebind");
             }
          }
@@ -328,16 +341,20 @@
 //            System.out.println("unbind "+name+"="+getBinding(name));
             if (getBinding(name) != null)
             {
+               SecurityManager sm = System.getSecurityManager();
+               Name fullName = (Name) prefix.clone();
+               fullName.addAll(name);
+               if(sm != null)
+               {
+                  JndiPermission perm = new JndiPermission(fullName, JndiPermission.UNBIND);
+                  sm.checkPermission(perm);
+               }
+               
                Binding newb = null;
                Binding oldb = removeBinding(name);
                // Notify event listeners
-               if(listeners != null)
-               {
-                  int type = NamingEvent.OBJECT_REMOVED;
-                  Name fullName = (Name) prefix.clone();
-                  fullName.addAll(name);
-                  this.fireEvent(fullName, oldb, newb, type, "unbind");
-               }
+               int type = NamingEvent.OBJECT_REMOVED;
+               this.fireEvent(fullName, oldb, newb, type, "unbind");
             }
             else
             {
@@ -354,9 +371,17 @@
 		Object result;
       if (name.isEmpty())
       {
+         SecurityManager sm = System.getSecurityManager();
+         if(sm != null)
+         {
+            JndiPermission perm = new JndiPermission(prefix, JndiPermission.LOOKUP);
+            sm.checkPermission(perm);
+         }
+         
          // Return this
          result = new NamingContext(null, (Name)(prefix.clone()), getRoot());
-      } else if (name.size() > 1)
+      }
+      else if (name.size() > 1)
       {
          // Recurse to find correct context
 //         System.out.println("lookup#"+name+"#");
@@ -365,7 +390,8 @@
          if (ctx instanceof NamingServer)
          {
             result = ((NamingServer)ctx).lookup(name.getSuffix(1));
-         } else if (ctx instanceof Reference)
+         }
+         else if (ctx instanceof Reference)
          {
             // Federation
             if (((Reference)ctx).get("nns") != null)
@@ -381,21 +407,36 @@
          {
             throw new NotContextException();
          }
-      } else
+      }
+      else
       {
          // Get object to return
          if (name.get(0).equals(""))
          {
-            result = new NamingContext(null, prefix, getRoot());
-         } else
+            SecurityManager sm = System.getSecurityManager();
+            if(sm != null)
+            {
+               JndiPermission perm = new JndiPermission(prefix, JndiPermission.LOOKUP);
+               sm.checkPermission(perm);
+            }
+            result = new NamingContext(null, (Name)(prefix.clone()), getRoot());
+         }
+         else
          {
 //            System.out.println("lookup "+name);
+            SecurityManager sm = System.getSecurityManager();
+            Name fullName = (Name)(prefix.clone());
+            fullName.addAll(name);
+            if(sm != null)
+            {
+               JndiPermission perm = new JndiPermission(fullName, JndiPermission.LOOKUP);
+               sm.checkPermission(perm);
+            }
+            
             Object res = getObject(name);
             
             if (res instanceof NamingServer)
             {
-               Name fullName = (Name)(prefix.clone());
-               fullName.addAll(name);
                result = new NamingContext(null, fullName, getRoot());
             }
             else
@@ -410,7 +451,14 @@
       throws NamingException
    {
       if (name.isEmpty())
-      {  
+      {
+         SecurityManager sm = System.getSecurityManager();
+         if(sm != null)
+         {
+            JndiPermission perm = new JndiPermission(prefix, JndiPermission.LIST);
+            sm.checkPermission(perm);
+         }
+
          ArrayList<NameClassPair> list = new ArrayList<NameClassPair>();
          for(Map.Entry<String, Binding> entry : table.entrySet())
          {
@@ -453,6 +501,13 @@
    {
       if (name.isEmpty())
       {
+         SecurityManager sm = System.getSecurityManager();
+         if(sm != null)
+         {
+            JndiPermission perm = new JndiPermission(prefix, JndiPermission.LIST_BINDINGS);
+            sm.checkPermission(perm);
+         }
+
          Collection bindings = table.values();
          Collection newBindings = new Vector(bindings.size());
          Iterator iter = bindings.iterator();
@@ -564,6 +619,12 @@
          {
             Name fullName = (Name) prefix.clone();
             fullName.addAll(name);
+            SecurityManager sm = System.getSecurityManager();
+            if(sm != null)
+            {
+               JndiPermission perm = new JndiPermission(fullName, JndiPermission.CREATE_SUBCONTEXT);
+               sm.checkPermission(perm);
+            }
             NamingServer subContext = createNamingServer(fullName, this);
             subCtx = new NamingContext(null, fullName, getRoot());
             setBinding(name, subContext, NamingContext.class.getName());
@@ -647,8 +708,8 @@
          if(nsparent.listeners != null)
          {
             eventMgr.fireEvent(fullName, oldb, newb, type, changeInfo, nsparent.listeners, scopes);
-            nsparent = nsparent.parent;
          }
+         nsparent = nsparent.parent;
       }
    }
 

Added: projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/JndiPermissionUnitTest.java
===================================================================
--- projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/JndiPermissionUnitTest.java	                        (rev 0)
+++ projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/JndiPermissionUnitTest.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jnp.test;
+
+import org.jnp.server.JndiPermission;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests of the JndiPermission/JndiPermissionCollection behavior
+ * 
+ * @author Scott.Stark at jboss.org
+ * @version $Revision$
+ */
+public class JndiPermissionUnitTest extends TestCase
+{
+   public void testBind()
+   {
+      JndiPermission any = new JndiPermission("<<ALL BINDINGS>>", "*");
+      JndiPermission path1 = new JndiPermission("/path1/*", "bind");
+      JndiPermission path1Recursive = new JndiPermission("/path1/-", "bind");
+
+      assertTrue("<<ALL BINDINGS>> implies /path1;bind", any.implies(path1));
+      assertTrue("<<ALL BINDINGS>> implies /path1;bind", any.implies(path1Recursive));
+      JndiPermission p = new JndiPermission("/path1/", "bind");
+      assertTrue(path1+" implies /path1/ bind", path1.implies(p));
+      assertTrue(path1Recursive+" implies /path1/ bind", path1Recursive.implies(p));
+      // A directory permission does not imply access to the unqualified path
+      p = new JndiPermission("/path1", "bind");
+      assertFalse(path1+" implies /path1;bind", path1.implies(p));
+      assertFalse(path1Recursive+" implies /path1;bind", path1Recursive.implies(p));
+      
+   }
+}


Property changes on: projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/JndiPermissionUnitTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision

Added: projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/NamingServerSecurityManagerUnitTest.java
===================================================================
--- projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/NamingServerSecurityManagerUnitTest.java	                        (rev 0)
+++ projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/NamingServerSecurityManagerUnitTest.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -0,0 +1,242 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jnp.test;
+
+import java.io.FilePermission;
+import java.io.SerializablePermission;
+import java.lang.reflect.ReflectPermission;
+import java.security.AccessControlException;
+import java.security.Permission;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+
+import javax.naming.InitialContext;
+
+import junit.framework.TestCase;
+
+import org.jnp.server.ExecutorEventMgr;
+import org.jnp.server.JndiPermission;
+import org.jnp.server.NamingBeanImpl;
+import org.jnp.test.support.QueueSecurityManager;
+import org.jnp.test.support.TestSecurityManager;
+
+/**
+ * Test using the NamingServer with a SecurityManager
+ * 
+ * @author Scott.Stark at jboss.org
+ * @version $Revision$
+ */
+public class NamingServerSecurityManagerUnitTest extends TestCase
+{
+   /** The actual namingMain service impl bean */
+   private NamingBeanImpl namingBean;
+   private InitialContext ic;
+
+   @Override
+   protected void setUp() throws Exception
+   {
+      namingBean = new NamingBeanImpl();
+      namingBean.setInstallGlobalService(true);
+      namingBean.setEventMgr(new ExecutorEventMgr());
+      namingBean.start();
+
+
+      Properties env = new Properties();
+      env.setProperty("java.naming.factory.initial", "org.jnp.interfaces.LocalOnlyContextFactory");
+      env.setProperty("java.naming.factory.url.pkgs", "org.jnp.interfaces");
+      ic = new InitialContext(env);
+   }
+
+   /**
+    * Test that the expected JndiPermission are passed to the SecurityManager
+    * @throws Exception
+    */
+   public void testOpPermissions()
+      throws Exception
+   {
+      QueueSecurityManager qsm = new QueueSecurityManager();
+      qsm.clearPerms();
+      System.setSecurityManager(qsm);
+
+      HashSet<JndiPermission> expectedPerms = new HashSet<JndiPermission>();
+      // expected doOps() permissions
+      expectedPerms.add(new JndiPermission("path1", "createSubcontext"));
+      expectedPerms.add(new JndiPermission("path1", "lookup"));
+      expectedPerms.add(new JndiPermission("path1", "list"));
+      expectedPerms.add(new JndiPermission("path1", "listBindings"));
+      expectedPerms.add(new JndiPermission("path1/x", "bind"));
+      expectedPerms.add(new JndiPermission("path1/x", "rebind"));
+      expectedPerms.add(new JndiPermission("path1/x", "unbind"));
+      expectedPerms.add(new JndiPermission("path1", "unbind"));
+      doOps();
+      // expected doBadOps() permissions
+      expectedPerms.add(new JndiPermission("path2", "createSubcontext"));
+      expectedPerms.add(new JndiPermission("path1x", "createSubcontext"));
+      expectedPerms.add(new JndiPermission("path1x", "rebind"));
+      expectedPerms.add(new JndiPermission("path1x", "lookup"));
+      expectedPerms.add(new JndiPermission("path1x", "list"));
+      expectedPerms.add(new JndiPermission("path1x", "listBindings"));
+      expectedPerms.add(new JndiPermission("path1x/x", "bind"));
+      expectedPerms.add(new JndiPermission("path1x", "unbind"));
+      doBadOps(false);
+
+      List<Permission> perms = qsm.getPerms();
+      for(Permission p : perms)
+      {
+         if(p instanceof JndiPermission)
+         {
+            System.out.println(p);
+            assertTrue(p+" is in expectedPerms", expectedPerms.contains(p));
+         }
+      }
+   }
+
+   /**
+    * Run with a TestSecurityManager that has a fixed set of allowed permissions
+    * @throws Exception
+    */
+   public void testSecurityManager()
+      throws Exception
+   {
+      TestSecurityManager tsm = new TestSecurityManager();
+      /*
+       JndiPermission 
+       */
+      tsm.addPermission(new JndiPermission("path1", "createSubcontext,lookup,list,listBindings,unbind"));
+      tsm.addPermission(new JndiPermission("path1x", "createSubcontext,unbind"));
+      tsm.addPermission(new JndiPermission("path1/*", "list,listBindings,lookup"));
+      tsm.addPermission(new JndiPermission("path1/x", "bind,rebind,unbind"));
+      tsm.addPermission(new RuntimePermission("exitVM"));
+      tsm.addPermission(new RuntimePermission("createClassLoader"));
+      tsm.addPermission(new ReflectPermission("suppressAccessChecks"));
+      tsm.addPermission(new SerializablePermission("enableSubstitution"));
+      tsm.addPermission(new FilePermission("<<ALL FILES>>", "read"));
+      System.setSecurityManager(tsm);
+
+      doOps();
+      doBadOps(true);
+   }
+
+   /**
+    * Naming ops that should succeed.
+    * @throws Exception
+    */
+   protected void doOps()
+      throws Exception
+   {
+      ic.createSubcontext("path1");
+      Object p1 = ic.lookup("path1");
+      ic.list("path1");
+      ic.listBindings("path1");
+      ic.bind("path1/x", "x.bind");
+      ic.rebind("path1/x", "x.rebind");
+      ic.unbind("path1/x");
+      ic.unbind("path1");
+   }
+   /**
+    * Naming ops that should fail.
+    * @throws Exception
+    */
+   protected void doBadOps(boolean expectFailure)
+      throws Exception
+   {
+      try
+      {
+         ic.createSubcontext("path2");
+         if(expectFailure)
+            fail("Was able to create path2 subcontext");
+      }
+      catch(AccessControlException e)
+      {
+         System.out.println(e);
+      }
+      ic.createSubcontext("path1x");
+      try
+      {
+         ic.rebind("path1x", "path1x.rebind");
+         if(expectFailure)
+            fail("Was able to rebind path1x subcontext");
+      }
+      catch(AccessControlException e)
+      {
+         System.out.println(e);
+      }
+      
+      try
+      {
+         ic.lookup("path1x");
+         if(expectFailure)
+            fail("Was able to lookup path1x subcontext");
+      }
+      catch(AccessControlException e)
+      {
+         System.out.println(e);
+      }
+
+      try
+      {
+         ic.list("path1x");
+         if(expectFailure)
+            fail("Was able to list path1x subcontext");
+      }
+      catch(AccessControlException e)
+      {
+         System.out.println(e);
+      }
+
+      try
+      {
+         ic.listBindings("path1x");
+         if(expectFailure)
+            fail("Was able to listBindings path1x subcontext");
+      }
+      catch(AccessControlException e)
+      {
+         System.out.println(e);
+      }
+
+      try
+      {
+         ic.bind("path1x/x", "x.bind");
+         if(expectFailure)
+            fail("Was able to bind path1x/x");
+      }
+      catch(AccessControlException e)
+      {
+         System.out.println(e);
+      }
+
+      try
+      {
+         ic.rebind("path1x/x", "x.rebind");
+         if(expectFailure)
+            fail("Was able to rebind path1x/x");
+      }
+      catch(AccessControlException e)
+      {
+         System.out.println(e);
+      }
+
+      ic.unbind("path1x");
+   }
+}


Property changes on: projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/NamingServerSecurityManagerUnitTest.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision

Added: projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/QueueSecurityManager.java
===================================================================
--- projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/QueueSecurityManager.java	                        (rev 0)
+++ projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/QueueSecurityManager.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jnp.test.support;
+
+import java.security.Permission;
+import java.util.ArrayList;
+
+/**
+ * @author Scott.Stark at jboss.org
+ * @version $Revision$
+ */
+public class QueueSecurityManager extends SecurityManager
+{
+   private ArrayList<Permission> perms = new ArrayList<Permission>();
+
+   
+   public ArrayList<Permission> getPerms()
+   {
+      return perms;
+   }
+   public void clearPerms()
+   {
+      perms.clear();
+   }
+
+   @Override
+   public void checkPermission(Permission perm)
+   {
+      perms.add(perm);
+   }
+
+}


Property changes on: projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/QueueSecurityManager.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision

Added: projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/TestSecurityManager.java
===================================================================
--- projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/TestSecurityManager.java	                        (rev 0)
+++ projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/TestSecurityManager.java	2008-10-02 14:43:05 UTC (rev 79030)
@@ -0,0 +1,60 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jnp.test.support;
+
+import java.security.Permission;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Scott.Stark at jboss.org
+ * @version $Revision$
+ */
+public class TestSecurityManager extends SecurityManager
+{
+   /** The set of allowed test permissions */
+   HashSet<Permission> testPermissions = new HashSet<Permission>();
+
+   public void addPermission(Permission p)
+   {
+      testPermissions.add(p);
+   }
+   public Set<Permission> getPermissions()
+   {
+      return testPermissions;
+   }
+
+   /**
+    * 
+    */
+   @Override
+   public void checkPermission(Permission perm)
+   {
+      for(Permission p : testPermissions)
+      {
+         if(p.implies(perm))
+            return;
+      }
+      System.out.println("checkPermission, "+perm);
+      super.checkPermission(perm);
+   }
+}


Property changes on: projects/naming/trunk/jnpserver/src/test/java/org/jnp/test/support/TestSecurityManager.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision




More information about the jboss-cvs-commits mailing list