FELIX-4362 Call ManagedService[Factory] methods as privileged actions

The privileged actions are called with an AccessControlContext
created from the ProtectionDomain of the called service's class.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1553904 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/BaseTracker.java b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/BaseTracker.java
index a6f073e..d8d93f4 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/BaseTracker.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/BaseTracker.java
@@ -19,6 +19,8 @@
 package org.apache.felix.cm.impl.helper;
 
 
+import java.security.AccessControlContext;
+import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -50,7 +52,6 @@
 
     private final boolean managedServiceFactory;
 
-
     protected BaseTracker( final ConfigurationManager cm, final boolean managedServiceFactory )
     {
         super( cm.getBundleContext(), ( managedServiceFactory ? ManagedServiceFactory.class.getName()
@@ -284,4 +285,10 @@
         return null;
     }
 
+
+    protected AccessControlContext getAccessControlContext( final Object ref )
+    {
+        return new AccessControlContext( new ProtectionDomain[]
+            { ref.getClass().getProtectionDomain() } );
+    }
 }
\ No newline at end of file
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceFactoryTracker.java b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceFactoryTracker.java
index 91ead4e..c668c0b 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceFactoryTracker.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceFactoryTracker.java
@@ -18,10 +18,15 @@
  */
 package org.apache.felix.cm.impl.helper;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.util.Dictionary;
 
 import org.apache.felix.cm.impl.ConfigurationManager;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedServiceFactory;
 
 public class ManagedServiceFactoryTracker extends BaseTracker<ManagedServiceFactory>
@@ -85,7 +90,7 @@
             {
                 Dictionary props = getProperties( properties, reference, configPid.toString(),
                     factoryPid.toString() );
-                service.updated( configPid.toString(), props );
+                updated( service, configPid.toString(), props );
                 configs.record( configPid, factoryPid, revision );
             }
             catch ( Throwable t )
@@ -112,7 +117,7 @@
             {
                 try
                 {
-                    service.deleted( configPid.toString() );
+                    deleted( service, configPid.toString() );
                     configs.record( configPid, factoryPid, -1 );
                 }
                 catch ( Throwable t )
@@ -126,4 +131,52 @@
             }
         }
     }
+
+
+    private void updated( final ManagedServiceFactory service, final String pid, final Dictionary properties )
+        throws ConfigurationException
+    {
+        if ( System.getSecurityManager() != null )
+        {
+            try
+            {
+                AccessController.doPrivileged( new PrivilegedExceptionAction()
+                {
+                    public Object run() throws ConfigurationException
+                    {
+                        service.updated( pid, properties );
+                        return null;
+                    }
+                }, getAccessControlContext( service ) );
+            }
+            catch ( PrivilegedActionException e )
+            {
+                throw ( ConfigurationException ) e.getException();
+            }
+        }
+        else
+        {
+            service.updated( pid, properties );
+        }
+    }
+
+
+    private void deleted( final ManagedServiceFactory service, final String pid )
+    {
+        if ( System.getSecurityManager() != null )
+        {
+            AccessController.doPrivileged( new PrivilegedAction()
+            {
+                public Object run()
+                {
+                    service.deleted( pid );
+                    return null;
+                }
+            }, getAccessControlContext( service ) );
+        }
+        else
+        {
+            service.deleted( pid );
+        }
+    }
 }
\ No newline at end of file
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceTracker.java b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceTracker.java
index 0d62181..0fd81fb 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceTracker.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceTracker.java
@@ -19,11 +19,15 @@
 package org.apache.felix.cm.impl.helper;
 
 
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.util.Dictionary;
 import java.util.Hashtable;
 
 import org.apache.felix.cm.impl.ConfigurationManager;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedService;
 
 
@@ -145,7 +149,7 @@
         {
             try
             {
-                srv.updated( properties );
+                updated( srv, properties );
                 configs.record( configPid, null, revision );
             }
             catch ( Throwable t )
@@ -157,5 +161,32 @@
                 this.ungetRealService( service );
             }
         }
-   }
+    }
+
+
+    private void updated( final ManagedService service, final Dictionary properties ) throws ConfigurationException
+    {
+        if ( System.getSecurityManager() != null )
+        {
+            try
+            {
+                AccessController.doPrivileged( new PrivilegedExceptionAction()
+                {
+                    public Object run() throws ConfigurationException
+                    {
+                        service.updated( properties );
+                        return null;
+                    }
+                }, getAccessControlContext( service ) );
+            }
+            catch ( PrivilegedActionException e )
+            {
+                throw ( ConfigurationException ) e.getException();
+            }
+        }
+        else
+        {
+            service.updated( properties );
+        }
+    }
 }
\ No newline at end of file
diff --git a/configadmin/src/main/resources/OSGI-INF/permissions.perm b/configadmin/src/main/resources/OSGI-INF/permissions.perm
index 44a34ba..98ba165 100644
--- a/configadmin/src/main/resources/OSGI-INF/permissions.perm
+++ b/configadmin/src/main/resources/OSGI-INF/permissions.perm
@@ -41,5 +41,9 @@
 # -> FilePersistenceManager
 (java.util.PropertyPermission "user.dir" "read")
 (java.io.FilePermission "-" "read,write,execute,delete")
+
 # -> ConfigurationManager
 (org.osgi.framework.ServicePermission "org.apache.felix.cm.PersistenceManager" "register")
+
+# -> BaseTracker.getAccessControlContext
+(java.lang.RuntimePermission "getProtectionDomain")