You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/04/27 10:05:38 UTC
svn commit: r768886 - in /commons/sandbox/runtime/trunk/src:
main/java/org/apache/commons/runtime/io/File.java
main/native/os/win32/file.c test/org/apache/commons/runtime/TestFile.java
Author: mturk
Date: Mon Apr 27 08:05:37 2009
New Revision: 768886
URL: http://svn.apache.org/viewvc?rev=768886&view=rev
Log:
Implement win32 prot
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java
commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java
Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java?rev=768886&r1=768885&r2=768886&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java Mon Apr 27 08:05:37 2009
@@ -18,6 +18,7 @@
import java.io.IOException;
import java.net.URI;
+import java.util.EnumSet;
/**
* An abstract representation of file and directory pathnames that
@@ -33,6 +34,8 @@
// Native methods from libacr.
private static native int ftype0(String pathname)
throws IOException, SecurityException;
+ private static native int fprot0(String pathname)
+ throws IOException, SecurityException;
private static native boolean mkslink0(String target, String link)
throws IOException, SecurityException,
UnsupportedOperationException;
@@ -175,6 +178,13 @@
return FileType.valueOf(fileType);
}
+ public EnumSet<FileProtection> getFileProtection()
+ throws IOException, SecurityException
+ {
+ int mode = fprot0(getPath());
+ return FileProtection.valueOf(mode);
+ }
+
/**
* Returns {@code true} if the file denoted by this abstract
* pathname is symbolic link.
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c?rev=768886&r1=768885&r2=768886&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/file.c Mon Apr 27 08:05:37 2009
@@ -247,3 +247,142 @@
} END_WITH_WSTR(lnkname);
return rv;
}
+
+static int free_localheap(void *heap) {
+ LocalFree(heap);
+ return 0;
+}
+
+static PSID worldid = NULL;
+
+static void free_world(void)
+{
+ if (worldid) {
+ FreeSid(worldid);
+ worldid = NULL;
+ }
+}
+
+/* Left bit shifts from World scope to given scope */
+typedef enum prot_scope_e {
+ prot_scope_world = 0,
+ prot_scope_group = 4,
+ prot_scope_user = 8
+} prot_scope_e;
+
+static int convert_prot(ACCESS_MASK acc, prot_scope_e scope)
+{
+ /* These choices are based on the single filesystem bit that controls
+ * the given behavior. They are -not- recommended for any set protection
+ * function, such a function should -set- use GENERIC_READ/WRITE/EXECUTE
+ */
+ int prot = 0;
+ if (acc & FILE_EXECUTE)
+ prot |= ACR_FPROT_WEXECUTE;
+ if (acc & FILE_WRITE_DATA)
+ prot |= ACR_FPROT_WWRITE;
+ if (acc & FILE_READ_DATA)
+ prot |= ACR_FPROT_WREAD;
+ return (prot << scope);
+}
+
+static int resolve_prot(PSID user, PSID group, PACL dacl)
+{
+ TRUSTEE_W ident = { NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID };
+ ACCESS_MASK acc;
+ int protection = 0;
+ /*
+ * This function is only invoked for WinNT,
+ * there is no reason for os_level testing here.
+ */
+ if (!worldid) {
+ SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_WORLD_SID_AUTHORITY;
+ if (AllocateAndInitializeSid(&SIDAuth, 1, SECURITY_WORLD_RID,
+ 0, 0, 0, 0, 0, 0, 0, &worldid))
+ atexit(free_world);
+ else
+ worldid = NULL;
+ }
+ if (user) {
+ ident.TrusteeType = TRUSTEE_IS_USER;
+ ident.ptstrName = user;
+ /* GetEffectiveRightsFromAcl isn't supported under Win9x,
+ * which shouldn't come as a surprize. Since we are passing
+ * TRUSTEE_IS_SID, always skip the A->W layer.
+ */
+ if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) {
+ protection |= convert_prot(acc, prot_scope_user);
+ }
+ }
+ /* Windows NT: did not return group rights.
+ * Windows 2000 returns group rights information.
+ * Since WinNT kernels don't follow the unix model of
+ * group associations, this all all pretty mute.
+ */
+ if (group) {
+ ident.TrusteeType = TRUSTEE_IS_GROUP;
+ ident.ptstrName = group;
+ if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) {
+ protection |= convert_prot(acc, prot_scope_group);
+ }
+ }
+ if (worldid) {
+ ident.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ ident.ptstrName = worldid;
+ if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) {
+ protection |= convert_prot(acc, prot_scope_world);
+ }
+ }
+ return protection;
+}
+
+ACR_DECLARE(int) ACR_FileProtectionGet(JNIEnv *_E, wchar_t *fname)
+{
+ int protection = 0;
+ PSID user = NULL, group = NULL;
+ PACL dacl = NULL;
+ SECURITY_INFORMATION sinf = 0;
+ PSECURITY_DESCRIPTOR pdesc = NULL;
+ int fix = 0;
+ int rc;
+
+ if (wcsncmp(fname, L"\\\\?\\", 4) == 0) {
+ fix = 4;
+ if (wcsncmp(fname + fix, L"UNC\\", 4) == 0) {
+ fname[6] = L'\\';
+ fix = 6;
+ }
+ }
+ sinf = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION;
+ rc = GetNamedSecurityInfoW(fname + fix,
+ SE_FILE_OBJECT, sinf,
+ &user,
+ &group,
+ &dacl,
+ NULL,
+ &pdesc);
+ if (rc == ERROR_SUCCESS) {
+ return resolve_prot(user, group, dacl);
+ }
+ else if (_E) {
+ if (ACR_STATUS_IS_EACCES(ACR_FROM_OS_ERROR(rc)))
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+ else
+ ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO,
+ ACR_FROM_OS_ERROR(rc));
+ }
+ return 0;
+}
+
+ACR_JNI_EXPORT_DECLARE(int, io_File, fprot0)(ACR_JNISTDARGS, jstring pathname)
+{
+ int prot = 0;
+
+ UNREFERENCED_O;
+ WITH_WSTR(pathname) {
+ prot = ACR_FileProtectionGet(_E, J2W(pathname));
+ } END_WITH_WSTR(pathname);
+
+ return prot;
+}
Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java?rev=768886&r1=768885&r2=768886&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java (original)
+++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java Mon Apr 27 08:05:37 2009
@@ -18,6 +18,7 @@
import org.apache.commons.runtime.io.*;
import junit.framework.*;
+import java.util.EnumSet;
/**
* File Test.
@@ -166,4 +167,13 @@
}
}
+ public void testProtection()
+ throws Exception
+ {
+ File f = new File("ffoo");
+ f.createNewFile();
+ EnumSet <FileProtection> fp = f.getFileProtection();
+ assertTrue("GWRITE", fp.contains(FileProtection.GREAD));
+ f.delete();
+ }
}