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();
+    }    
 }