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 ka...@apache.org on 2014/04/23 14:44:23 UTC
svn commit: r1589396 - in
/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io:
FilePermissionServiceImpl.java FileUtil.java
Author: kahatlen
Date: Wed Apr 23 12:44:23 2014
New Revision: 1589396
URL: http://svn.apache.org/r1589396
Log:
DERBY-6521: Improve error handling when restricting file permissions
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FilePermissionServiceImpl.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FileUtil.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FilePermissionServiceImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FilePermissionServiceImpl.java?rev=1589396&r1=1589395&r2=1589396&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FilePermissionServiceImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FilePermissionServiceImpl.java Wed Apr 23 12:44:23 2014
@@ -30,44 +30,71 @@ import java.nio.file.attribute.AclEntryP
import java.nio.file.attribute.AclEntryType;
import java.nio.file.attribute.AclFileAttributeView;
import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFilePermission;
import java.util.Collections;
+import java.util.EnumSet;
/**
- * Class that limits file permissions using an {@code AclFileAttributeView}.
+ * <p>
+ * Class that limits file permissions using a {@code PosixFileAttributeView}
+ * or an {@code AclFileAttributeView}.
+ * </p>
+ *
+ * <p>
* For use by {@link FileUtil#limitAccessToOwner(File)}.
+ * </p>
*/
final class FilePermissionServiceImpl implements FilePermissionService {
public boolean limitAccessToOwner(File file) throws IOException {
Path fileP = file.toPath();
- // If we have a posix view, just return and fall back on
- // the JDK 6 approach.
PosixFileAttributeView posixView = Files.getFileAttributeView(
fileP, PosixFileAttributeView.class);
if (posixView != null) {
- return false;
+
+ // This is a POSIX file system. Usually,
+ // FileUtil.limitAccessToOwnerViaFile() will successfully set
+ // the permissions on such file systems using the java.io.File
+ // class, so we don't get here. If, however, that approach failed,
+ // we try again here using a PosixFileAttributeView. That's likely
+ // to fail too, but at least now we will get an IOException that
+ // explains why it failed.
+
+ EnumSet<PosixFilePermission> perms = EnumSet.of(
+ PosixFilePermission.OWNER_READ,
+ PosixFilePermission.OWNER_WRITE);
+
+ if (file.isDirectory()) {
+ perms.add(PosixFilePermission.OWNER_EXECUTE);
+ }
+
+ posixView.setPermissions(perms);
+
+ return true;
}
AclFileAttributeView aclView = Files.getFileAttributeView(
fileP, AclFileAttributeView.class);
- if (aclView == null) {
- return false;
- }
+ if (aclView != null) {
+
+ // Since we have an AclFileAttributeView which is not a
+ // PosixFileAttributeView, we probably have an NTFS file
+ // system.
+
+ // Remove existing ACEs, build a new one which simply
+ // gives all possible permissions to current owner.
+ AclEntry ace = AclEntry.newBuilder()
+ .setPrincipal(Files.getOwner(fileP))
+ .setType(AclEntryType.ALLOW)
+ .setPermissions(EnumSet.allOf(AclEntryPermission.class))
+ .build();
- // Since we have an AclFileAttributeView which is not a
- // PosixFileAttributeView, we probably have an NTFS file
- // system.
-
- // Remove existing ACEs, build a new one which simply
- // gives all possible permissions to current owner.
- AclEntry ace = AclEntry.newBuilder()
- .setPrincipal(Files.getOwner(fileP))
- .setType(AclEntryType.ALLOW)
- .setPermissions(AclEntryPermission.values())
- .build();
+ aclView.setAcl(Collections.singletonList(ace));
- aclView.setAcl(Collections.singletonList(ace));
+ return true;
+ }
- return true;
+ // We don't know how to set permissions on this file system.
+ return false;
}
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FileUtil.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FileUtil.java?rev=1589396&r1=1589395&r2=1589396&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FileUtil.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/FileUtil.java Wed Apr 23 12:44:23 2014
@@ -36,7 +36,6 @@ import java.net.URL;
import org.apache.derby.iapi.reference.Property;
import org.apache.derby.iapi.services.info.JVMInfo;
import org.apache.derby.iapi.services.property.PropertyUtil;
-import org.apache.derby.shared.common.sanity.SanityManager;
/**
A set of public static methods for dealing with File objects.
@@ -483,21 +482,43 @@ public abstract class FileUtil {
}
/**
+ * <p>
* Use when creating new files. If running on Unix,
* limit read and write permissions on {@code file} to owner if {@code
* derby.storage.useDefaultFilePermissions == false}.
- * <p/>
+ * </p>
+ *
+ * <p>
* If the property is not specified, we use restrictive permissions anyway
* iff running with the server server started from the command line.
- * <p/>
+ * </p>
+ *
+ * <p>
* On Unix, this is equivalent to running with umask 0077.
- * <p/>
+ * </p>
+ *
+ * <p>
* On Windows, with FAT/FAT32, we lose, since the fs does not support
* permissions, only a read-only flag.
- * <p/>
+ * </p>
+ *
+ * <p>
* On Windows, with NTFS with ACLs, if running with Java 7 or higher, we
* limit access also for Windows using the new {@code
* java.nio.file.attribute} package.
+ * </p>
+ *
+ * <p>
+ * When restricted file access is enabled (either explicitly or by
+ * default) errors are handled like this: When running on JDK 7 or higher,
+ * and the file system can be accessed either via a PosixFileAttributeView
+ * or via an AclFileAttributeView, any IOException reported when trying
+ * to restrict the permissions will also be thrown by this method. In
+ * all other cases, it will do its best to limit the permissions using
+ * the {@code java.io.File} methods ({@code setReadable()},
+ * {@code setWritable()}, {@code setExecutable()}), but it won't throw
+ * any exceptions if the permissions cannot be set that way.
+ * </p>
*
* @param file assumed to be just created
* @throws IOException if an I/O error happens when trying to change the
@@ -525,65 +546,67 @@ public abstract class FileUtil {
}
}
- if (limitAccessToOwnerViaACLs(file)) {
+ // First attempt to limit access using the java.io.File class.
+ // If it is successful, that's it and we're done.
+ if (limitAccessToOwnerViaFile(file)) {
return;
}
- //
+ // We couldn't limit the access using the java.io.File class. Try
+ // again with a FileAttributeView if it is supported. We may have
+ // more luck with that approach. For example, with NTFS on Windows,
+ // the java.io.File class won't be able to limit access, but the
+ // FileAttributeView will.
+ limitAccessToOwnerViaFileAttributeView(file);
+ }
+
+ /**
+ * Limit access to owner using methods in the {@code java.io.File} class.
+ * Those methods are available on all Java versions from 6 and up, but
+ * they are not fully functional on all file systems.
+ *
+ * @param file the file to limit access to
+ * @return {@code true} on success, or {@code false} if some of the
+ * permissions could not be changed
+ */
+ private static boolean limitAccessToOwnerViaFile(File file) {
+
// First switch off all write access
- //
- assertTrue(file.setWritable(false, false));
+ boolean success = file.setWritable(false, false);
- //
// Next, switch on write again, but for owner only
- //
- assertTrue(file.setWritable(true, true));
+ success &= file.setWritable(true, true);
- //
// First switch off all read access
- //
- assertTrue(file.setReadable(false, false));
+ success &= file.setReadable(false, false);
- //
// Next, switch on read access again, but for owner only
- //
- assertTrue(file.setReadable(true, true));
+ success &= file.setReadable(true, true);
if (file.isDirectory()) {
- //
// First switch off all exec access
- //
- assertTrue(file.setExecutable(false, false));
+ success &= file.setExecutable(false, false);
- //
// Next, switch on exec again, but for owner only
- //
- assertTrue(file.setExecutable(true, true));
+ success &= file.setExecutable(true, true);
}
- }
- private static void assertTrue(boolean b) {
- // We should always have the permission to modify the access since have
- // just created the file. On some file systems, some operations will
- // not work, though, notably FAT/FAT32, as well as NTFS on java < 7, so
- // we ignore it the failure.
- if (SanityManager.DEBUG) {
- if (!b) {
- String os =
- PropertyUtil.getSystemProperty("os.name").toLowerCase();
-
- if (os.indexOf("windows") >= 0) {
- // expect this to fail, Java 6 on Windows doesn't cut it,
- // known not to work.
- } else {
- SanityManager.THROWASSERT(
- "File.set{RWX} failed on this file system");
- }
- }
- }
+ return success;
}
- private static boolean limitAccessToOwnerViaACLs(File file)
+ /**
+ * Limit access to owner using a
+ * {@code java.nio.file.attribute.FileAttributeView}.
+ * Such views are only available on Java 7 and higher, and only on
+ * file systems that support changing file permissions. Currently,
+ * this is supported on POSIX file systems and file systems that
+ * maintain access control lists (ACLs).
+ *
+ * @param file the file to limit access to
+ * @return {@code true} on success, or {@code false} if some of the
+ * permissions could not be changed
+ */
+ private static boolean limitAccessToOwnerViaFileAttributeView(File file)
throws IOException {
// See if we are running on JDK 7 so we can deny access