You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by da...@apache.org on 2011/10/05 04:30:18 UTC

svn commit: r1179042 - /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/RestrictiveFilePermissionsTest.java

Author: dag
Date: Wed Oct  5 02:30:18 2011
New Revision: 1179042

URL: http://svn.apache.org/viewvc?rev=1179042&view=rev
Log:
DERBY-5363 Tighten permissions of DB files to owner with >= JDK7

Patch derby-5363-followup-linux.

RestrictiveFilePermissionsTest for this feature broke on some
platforms (thanks to Kathey for noticing). Apparently, the ACL view of
Posix file system permissions is not available for all Unix/Linux
versions in JDK 1.7 (I had tested on Solaris 11 and Windows). The
changes in the test now fall back on using
PosixFileAttributeView#readAttributes if the ACL view is not
available.


Modified:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/RestrictiveFilePermissionsTest.java

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/RestrictiveFilePermissionsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/RestrictiveFilePermissionsTest.java?rev=1179042&r1=1179041&r2=1179042&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/RestrictiveFilePermissionsTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/engine/RestrictiveFilePermissionsTest.java Wed Oct  5 02:30:18 2011
@@ -24,6 +24,7 @@ import java.io.File;
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.Field;
 import java.net.URL;
 import java.security.AccessController;
 import java.security.PrivilegedExceptionAction;
@@ -36,8 +37,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
 import java.util.Set;
+import java.util.HashSet;
 import javax.sql.DataSource;
-import junit.framework.Assert;
 import junit.framework.Test;
 import junit.framework.TestSuite;
 import org.apache.derby.drda.NetworkServerControl;
@@ -91,7 +92,6 @@ public class RestrictiveFilePermissionsT
 
         supportsLaxTesting =
             checkAccessToOwner(
-                null,
                 f,
                 false,
                 UNKNOWN);
@@ -110,7 +110,7 @@ public class RestrictiveFilePermissionsT
         // setting of the property derby.storage.useDefaultFilePermissions.
         // The extra setup file is for testJarFiles.
 
-        TestSuite totalSuite = new TestSuite();
+        TestSuite totalSuite = new TestSuite("RestrictiveFilePermissionsTest");
 
         Properties p = new Properties();
         p.put("derby.storage.useDefaultFilePermissions", "false");
@@ -177,16 +177,14 @@ public class RestrictiveFilePermissionsT
     public void testDerbyDotLog() throws Exception {
         File derbydotlog = new File(home, derbyDotLog);
 
-        checkAccessToOwner(
-            this, derbydotlog, POSITIVE);
+        checkAccessToOwner(derbydotlog, POSITIVE);
     }
 
 
     public void testDbDirectory() throws Exception {
         File derbyDbDir = new File(home, dbName);
 
-        checkAccessToOwner(
-            this, derbyDbDir, POSITIVE);
+        checkAccessToOwner(derbyDbDir, POSITIVE);
     }
 
 
@@ -194,7 +192,7 @@ public class RestrictiveFilePermissionsT
         File servProp = new File(home, dbName + "/" + "service.properties");
 
         checkAccessToOwner(
-            this, servProp, POSITIVE);
+            servProp, POSITIVE);
     }
 
 
@@ -206,7 +204,7 @@ public class RestrictiveFilePermissionsT
                          "on commit preserve rows not logged").executeUpdate();
 
         checkAccessToOwner(
-            this, tmp, true, POSITIVE);
+            tmp, true, POSITIVE);
     }
 
 
@@ -214,12 +212,10 @@ public class RestrictiveFilePermissionsT
         File dbLck = new File(home, dbName + "/" + "db.lck");
         File dbexLck = new File(home, dbName + "/" + "dbex.lck");
 
-        checkAccessToOwner(
-            this, dbLck, POSITIVE);
+        checkAccessToOwner(dbLck, POSITIVE);
 
         if (PrivilegedFileOpsForTests.exists(dbexLck)) {
-            checkAccessToOwner(
-                    this, dbexLck, POSITIVE);
+            checkAccessToOwner(dbexLck, POSITIVE);
         }
     }
 
@@ -228,7 +224,7 @@ public class RestrictiveFilePermissionsT
         File seg0 = new File(home, dbName + "/" + "seg0");
 
         checkAccessToOwner(
-            this, seg0, true, POSITIVE);
+            seg0, true, POSITIVE);
     }
 
 
@@ -236,7 +232,7 @@ public class RestrictiveFilePermissionsT
         File seg0 = new File(home, dbName + "/" + "log");
 
         checkAccessToOwner(
-            this, seg0, true, POSITIVE);
+            seg0, true, POSITIVE);
     }
 
 
@@ -255,8 +251,7 @@ public class RestrictiveFilePermissionsT
                         "    NULL)"); // code set
         File exp = new File(home, dbName + "/" + exportFileName);
 
-        checkAccessToOwner(
-            this, exp, POSITIVE);
+        checkAccessToOwner(exp, POSITIVE);
 
         // Make a lob table and insert one row
         s.executeUpdate("create table lobtable(i int, c clob)");
@@ -282,11 +277,9 @@ public class RestrictiveFilePermissionsT
         File expLob = new File(home, dbName + "/" + exportLobFileName);
 
         // Check resuling exported files
-        checkAccessToOwner(
-            this, exp2, POSITIVE);
+        checkAccessToOwner(exp2, POSITIVE);
 
-        checkAccessToOwner(
-            this, expLob, POSITIVE);
+        checkAccessToOwner(expLob, POSITIVE);
     }
 
 
@@ -318,7 +311,7 @@ public class RestrictiveFilePermissionsT
         File seg0 = new File(home, dbName + "/" + "seg0");
 
         checkAccessToOwner(
-            this, seg0, true, POSITIVE);
+            seg0, true, POSITIVE);
     }
 
 
@@ -345,7 +338,7 @@ public class RestrictiveFilePermissionsT
         File seg0 = new File(home, dbName + "/" + "seg0");
 
         checkAccessToOwner(
-            this, seg0, true, POSITIVE);
+            seg0, true, POSITIVE);
     }
 
 
@@ -374,7 +367,7 @@ public class RestrictiveFilePermissionsT
 
         File fbd = new File(fullBackupDir);
         checkAccessToOwner(
-            this, fbd, true, POSITIVE);
+            fbd, true, POSITIVE);
 
         // Prepare to restore
         TestConfiguration.getCurrent().shutdownDatabase();
@@ -390,7 +383,7 @@ public class RestrictiveFilePermissionsT
 
         final File db = new File(home, dbName);
         checkAccessToOwner(
-            this, db, true, POSITIVE);
+            db, true, POSITIVE);
 
         con.close();
 
@@ -403,7 +396,7 @@ public class RestrictiveFilePermissionsT
         final File newDb = new File(home, dbName2);
 
         checkAccessToOwner(
-            this, newDb, true, POSITIVE);
+            newDb, true, POSITIVE);
         con2.close();
 
         // close down both
@@ -442,7 +435,7 @@ public class RestrictiveFilePermissionsT
         File jarsDir = new File(home, dbName + "/" + "jar");
 
         checkAccessToOwner(
-            this, jarsDir, true, POSITIVE);
+            jarsDir, true, POSITIVE);
     }
 
 
@@ -461,7 +454,7 @@ public class RestrictiveFilePermissionsT
         File traceDirF = new File(traceDir);
 
         checkAccessToOwner(
-            this, traceDirF, true, POSITIVE);
+            traceDirF, true, POSITIVE);
         nsctrl.shutdown();
         assertDirectoryDeleted(traceDirF);
     }
@@ -479,7 +472,7 @@ public class RestrictiveFilePermissionsT
         File traceDirF = new File(traceDir);
 
         checkAccessToOwner(
-            this, traceDirF, true, NEGATIVE);
+            traceDirF, true, NEGATIVE);
 
         nsctrl.shutdown();
         assertDirectoryDeleted(traceDirF);
@@ -488,8 +481,7 @@ public class RestrictiveFilePermissionsT
 
     public void dotestEmbeddedIsLax() throws Exception {
         File derbydotlogF = new File(home, derbyDotLog + ".lax");
-        checkAccessToOwner(
-            this, derbydotlogF, NEGATIVE);
+        checkAccessToOwner(derbydotlogF, NEGATIVE);
     }
 
 
@@ -510,6 +502,8 @@ public class RestrictiveFilePermissionsT
     private static Class aclEntryClz;
     private static Class aclFileAttributeViewClz;
     private static Class posixFileAttributeViewClz;
+    private static Class posixFileAttributesClz;
+    private static Class posixFilePermissionClz;
     private static Class userPrincipalClz;
     private static Class linkOptionArrayClz;
     private static Class linkOptionClz;
@@ -523,8 +517,17 @@ public class RestrictiveFilePermissionsT
     private static Method getAcl;
     private static Method principal;
     private static Method getName;
-    private static Method permissions;
-
+    private static Method permissionsAcl;
+    private static Method permissionsPosix;
+    private static Method readAttributes;
+
+    private static Field GROUP_EXECUTE;
+    private static Field GROUP_READ;
+    private static Field GROUP_WRITE;
+    private static Field OTHERS_EXECUTE;
+    private static Field OTHERS_READ;
+    private static Field OTHERS_WRITE;
+    private static Set unwantedPermissions;
     /**
      * Check that the file has access only for the owner. Will throw (JUnit
      * failure) if permissions are not strict.
@@ -538,18 +541,16 @@ public class RestrictiveFilePermissionsT
      * we have no way in Java of checking the results in a portable way. So, if
      * we do not have at least Java 7, this method will be a no-op.
      *
-     * @param test the current test
      * @param file (or directory) for which we want to check permissions
      * @param expectedOutcome NEGATIVE or POSITIVE
      * @see #checkAccessToOwner(BaseJDBCTestCase, File, boolean, int)
      */
 
     public static void checkAccessToOwner(
-            BaseJDBCTestCase test,
             final File file,
             int expectedOutcome) throws Exception {
 
-        checkAccessToOwner(test, file, false, expectedOutcome);
+        checkAccessToOwner(file, false, expectedOutcome);
     }
 
 
@@ -558,7 +559,6 @@ public class RestrictiveFilePermissionsT
      * checkAccessToOwner}, but if {@code doContents} is true, also check files
      * directly contained in this file qua directory (not recursively).
      *
-     * @param test
      * @param file ((or directory) for which we want to check permissions
      * @param doContents if a directory, an error to call with true if not
      * @param expectedOutcome NEGATIVE, POSITIVE or UNKNOWN
@@ -566,7 +566,6 @@ public class RestrictiveFilePermissionsT
      *              UNKNOWN)
      */
     private static boolean checkAccessToOwner(
-            final BaseJDBCTestCase test,
             final File file,
             final boolean doContents,
             final int expectedOutcome) throws Exception {
@@ -574,14 +573,14 @@ public class RestrictiveFilePermissionsT
         // manager.
         if (doContents) {
             // visit immediately contained file in this directory also
-            checkAccessToOwner(test, file, false, expectedOutcome);
+            checkAccessToOwner(file, false, expectedOutcome);
 
             AccessController.doPrivileged(new PrivilegedExceptionAction() {
                 public Object run() throws Exception {
                     File [] files = file.listFiles();
                     for (int i = 0; i < files.length; i++){
                         checkAccessToOwner(
-                            test, files[i], false, expectedOutcome);
+                            files[i], false, expectedOutcome);
                     }
                     return null;
                 }});
@@ -591,100 +590,121 @@ public class RestrictiveFilePermissionsT
             (Boolean)AccessController.
             doPrivileged(new PrivilegedExceptionAction() {
 
-                    public Object run() throws Exception {
-                        // lazy initialization
-                        if (!initialized) {
-                            initialized = true;
-
-                            // If found, we have >= Java 7.
-                            filesClz = Class.forName(
-                                "java.nio.file.Files");
-                            pathClz = Class.forName(
-                                "java.nio.file.Path");
-                            pathsClz = Class.forName(
-                                "java.nio.file.Paths");
-                            aclEntryClz = Class.forName(
-                                "java.nio.file.attribute.AclEntry");
-                            aclFileAttributeViewClz = Class.forName(
-                                "java.nio.file.attribute." +
-                                "AclFileAttributeView");
-                            posixFileAttributeViewClz = Class.forName(
-                                "java.nio.file.attribute." +
-                                "PosixFileAttributeView");
-                            userPrincipalClz = Class.forName(
-                                "java.nio.file.attribute.UserPrincipal");
-                            linkOptionArrayClz = Class.forName(
-                                "[Ljava.nio.file.LinkOption;");
-                            linkOptionClz = Class.forName(
-                                "java.nio.file.LinkOption");
-                            stringArrayClz = Class.forName(
-                                "[Ljava.lang.String;");
-                            aclEntryBuilderClz = Class.forName(
-                                "java.nio.file.attribute.AclEntry$Builder");
-                            aclEntryTypeClz = Class.forName(
-                                "java.nio.file.attribute.AclEntryType");
-
-                            get = pathsClz.
-                                getMethod("get",
-                                          new Class[]{String.class,
-                                                      stringArrayClz});
-
-                            getFileAttributeView = filesClz.
-                                getMethod("getFileAttributeView",
-                                          new Class[]{pathClz,
-                                                      Class.class,
-                                                      linkOptionArrayClz});
-
-                            getOwner = filesClz.
-                                getMethod(
-                                    "getOwner",
-                                    new Class[]{pathClz,
-                                                linkOptionArrayClz});
-                            getAcl = aclFileAttributeViewClz.
-                                getMethod("getAcl", new Class[]{});
-                            principal = aclEntryClz.
-                                getMethod("principal", new Class[]{});
-                            getName = userPrincipalClz.
-                                getMethod("getName", new Class[]{});
-                            permissions = aclEntryClz.
-                                getMethod("permissions", new Class[]{});
-                        }
-
-                        // Only used with expectedOutcome == UNKNOWN, otherwise
-                        // we throw:
-                        boolean someThingBeyondOwnerFound = false;
-
-                        // We have Java 7. We need to call reflectively, since
-                        // the source level isn't yet at Java 7.
-                        try {
-                            Object fileP = get.invoke(
-                                null, new Object[]{file.getPath(),
-                                                   new String[]{}});
-
-                            Object view = getFileAttributeView.invoke(
-                                null,
-                                new Object[]{
-                                    fileP,
-                                    aclFileAttributeViewClz,
-                                    Array.newInstance(linkOptionClz, 0)});
-
-                            if (view == null) {
-                                // ACLs not supported on this platform
-                                fail();
-                            }
-
-                            // If we have a posix view, we can use ACLs to
-                            // interface the usual Unix permission masks via
-                            // the special principals OWNER@, GROUP@ and
-                            // EVERYONE@
+                public Object run() throws Exception {
+                    // lazy initialization
+                    if (!initialized) {
+                        initialized = true;
+
+                        // If found, we have >= Java 7.
+                        filesClz = Class.forName(
+                            "java.nio.file.Files");
+                        pathClz = Class.forName(
+                            "java.nio.file.Path");
+                        pathsClz = Class.forName(
+                            "java.nio.file.Paths");
+                        aclEntryClz = Class.forName(
+                            "java.nio.file.attribute.AclEntry");
+                        aclFileAttributeViewClz = Class.forName(
+                            "java.nio.file.attribute." +
+                            "AclFileAttributeView");
+                        posixFileAttributeViewClz = Class.forName(
+                            "java.nio.file.attribute." +
+                            "PosixFileAttributeView");
+                        posixFileAttributesClz = Class.forName(
+                            "java.nio.file.attribute." +
+                            "PosixFileAttributes");
+                        posixFilePermissionClz = Class.forName(
+                            "java.nio.file.attribute." +
+                            "PosixFilePermission");
+                        userPrincipalClz = Class.forName(
+                            "java.nio.file.attribute.UserPrincipal");
+                        linkOptionArrayClz = Class.forName(
+                            "[Ljava.nio.file.LinkOption;");
+                        linkOptionClz = Class.forName(
+                            "java.nio.file.LinkOption");
+                        stringArrayClz = Class.forName(
+                            "[Ljava.lang.String;");
+                        aclEntryBuilderClz = Class.forName(
+                            "java.nio.file.attribute.AclEntry$Builder");
+                        aclEntryTypeClz = Class.forName(
+                            "java.nio.file.attribute.AclEntryType");
+
+                        get = pathsClz.
+                            getMethod("get",
+                                      new Class[]{String.class,
+                                                  stringArrayClz});
+
+                        getFileAttributeView = filesClz.
+                            getMethod("getFileAttributeView",
+                                      new Class[]{pathClz,
+                                                  Class.class,
+                                                  linkOptionArrayClz});
+
+                        getOwner = filesClz.
+                            getMethod(
+                                "getOwner",
+                                new Class[]{pathClz,
+                                            linkOptionArrayClz});
+                        getAcl = aclFileAttributeViewClz.
+                            getMethod("getAcl", new Class[]{});
+                        principal = aclEntryClz.
+                            getMethod("principal", new Class[]{});
+                        getName = userPrincipalClz.
+                            getMethod("getName", new Class[]{});
+                        permissionsAcl = aclEntryClz.
+                            getMethod("permissions", new Class[]{});
+                        permissionsPosix = posixFileAttributesClz.
+                            getMethod("permissions", new Class[]{});
+                        readAttributes = posixFileAttributeViewClz.
+                            getMethod("readAttributes", new Class[]{});
+
+                        GROUP_EXECUTE =
+                            posixFilePermissionClz.getField("GROUP_EXECUTE");
+                        GROUP_READ =
+                            posixFilePermissionClz.getField("GROUP_READ");
+                        GROUP_WRITE =
+                            posixFilePermissionClz.getField("GROUP_WRITE");
+                        OTHERS_EXECUTE =
+                            posixFilePermissionClz.getField("OTHERS_EXECUTE");
+                        OTHERS_READ =
+                            posixFilePermissionClz.getField("OTHERS_READ");
+                        OTHERS_WRITE =
+                            posixFilePermissionClz.getField("OTHERS_WRITE");
+                        unwantedPermissions = new HashSet();
+                        unwantedPermissions.add(GROUP_EXECUTE.get(null));
+                        unwantedPermissions.add(GROUP_READ.get(null));
+                        unwantedPermissions.add(GROUP_WRITE.get(null));
+                        unwantedPermissions.add(OTHERS_EXECUTE.get(null));
+                        unwantedPermissions.add(OTHERS_READ.get(null));
+                        unwantedPermissions.add(OTHERS_WRITE.get(null));
+                    }
 
-                            Object posixView = getFileAttributeView.invoke(
-                                null,
-                                new Object[]{
-                                    fileP,
-                                    posixFileAttributeViewClz,
-                                    Array.newInstance(linkOptionClz, 0)});
+                    // Only used with expectedOutcome == UNKNOWN, otherwise
+                    // we throw:
+                    boolean someThingBeyondOwnerFound = false;
+
+                    // We have Java 7. We need to call reflectively, since
+                    // the source level isn't yet at Java 7.
+                    try {
+                        Object fileP = get.invoke(
+                            null, new Object[]{file.getPath(),
+                                               new String[]{}});
+
+                        Object aclView = getFileAttributeView.invoke(
+                            null,
+                            new Object[]{
+                                fileP,
+                                aclFileAttributeViewClz,
+                                Array.newInstance(linkOptionClz, 0)});
+
+                        Object posixView = getFileAttributeView.invoke(
+                            null,
+                            new Object[]{
+                                fileP,
+                                posixFileAttributeViewClz,
+                                Array.newInstance(linkOptionClz, 0)});
 
+                        if (aclView != null) { // Windows, Solaris 11
                             Object owner = getOwner.invoke(
                                 null,
                                 new Object[]{
@@ -692,7 +712,7 @@ public class RestrictiveFilePermissionsT
                                     Array.newInstance(linkOptionClz, 0)});
 
                             List oldAcl =
-                                (List)getAcl.invoke(view, (Object[])null);
+                                (List)getAcl.invoke(aclView, (Object[])null);
 
                             for (Iterator i = oldAcl.iterator(); i.hasNext();) {
                                 Object ace = i.next();
@@ -710,7 +730,7 @@ public class RestrictiveFilePermissionsT
                                         princName.equals("GROUP@") ||
                                         princName.equals("EVERYONE@")) {
 
-                                        Set s = (Set)permissions.invoke(
+                                        Set s = (Set)permissionsAcl.invoke(
                                             ace,
                                             (Object[])null);
 
@@ -741,38 +761,58 @@ public class RestrictiveFilePermissionsT
 
                                 }
                             }
-
-                            if (expectedOutcome == NEGATIVE &&
-                                    !someThingBeyondOwnerFound) {
-                                fail(
-                                    "unexpected restrictive access: " + file);
-                            }
-
-                        } catch (IllegalAccessException e) {
-                            // coding error
-                            if (SanityManager.DEBUG) {
-                                SanityManager.THROWASSERT(e);
-                            }
-                        } catch (IllegalArgumentException e) {
-                            // coding error
-                            if (SanityManager.DEBUG) {
-                                SanityManager.THROWASSERT(e);
+                        } else if (posixView != null) {
+                            Object posixFileAttributes =
+                                readAttributes.invoke(posixView,
+                                                      new Object[]{});
+                            Set permissionsSet =
+                                (Set)permissionsPosix.invoke(
+                                    posixFileAttributes, new Object[]{});
+
+                            for (Iterator i = permissionsSet.iterator();
+                                 i.hasNext();) {
+                                Object perm = i.next();
+
+                                if (unwantedPermissions.contains(perm)) {
+                                    someThingBeyondOwnerFound = true;
+                                    break;
+                                }
                             }
-                        } catch (InvocationTargetException e) {
-                            throw e;
+                        } else {
+                            fail();
                         }
 
-                        if (test != null) {
-                            test.println("checked perms on: " + file);
+                        if (expectedOutcome == NEGATIVE &&
+                                !someThingBeyondOwnerFound) {
+                            fail(
+                                "unexpected restrictive access: " + file);
                         }
 
-                        if (expectedOutcome == UNKNOWN &&
-                                someThingBeyondOwnerFound) {
-                            return Boolean.TRUE;
-                        } else {
-                            return Boolean.FALSE;
+                    } catch (IllegalAccessException e) {
+                        // coding error
+                        if (SanityManager.DEBUG) {
+                            SanityManager.THROWASSERT(e);
+                        }
+                    } catch (IllegalArgumentException e) {
+                        // coding error
+                        if (SanityManager.DEBUG) {
+                            SanityManager.THROWASSERT(e);
                         }
-                    }});
+                    } catch (InvocationTargetException e) {
+                        throw e;
+                    }
+
+                    if (expectedOutcome != UNKNOWN) {
+                        println("checked perms on: " + file);
+                    }
+
+                    if (expectedOutcome == UNKNOWN &&
+                            someThingBeyondOwnerFound) {
+                        return Boolean.TRUE;
+                    } else {
+                        return Boolean.FALSE;
+                    }
+                }});
 
         return result.booleanValue();
     }