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/05/23 17:14:50 UTC

svn commit: r777940 - in /commons/sandbox/runtime/trunk/src: main/java/org/apache/commons/runtime/io/File.java main/native/include/acr_file.h main/native/os/unix/file.c main/native/os/win32/file.c test/org/apache/commons/runtime/TestFile.java

Author: mturk
Date: Sat May 23 15:14:50 2009
New Revision: 777940

URL: http://svn.apache.org/viewvc?rev=777940&view=rev
Log:
Implement file protection setter

Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/File.java
    commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h
    commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c
    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=777940&r1=777939&r2=777940&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 Sat May 23 15:14:50 2009
@@ -36,6 +36,8 @@
                                         throws IOException, SecurityException;
     private static native int       fprot0(String pathname)
                                         throws IOException, SecurityException;
+    private static native boolean   fprot1(String pathname, int prot)
+                                        throws IOException, SecurityException;
     private static native boolean   mkslink0(String target, String link)
                                         throws IOException, SecurityException,
                                                UnsupportedOperationException;
@@ -185,6 +187,12 @@
         return FileProtection.valueOf(mode);
     }
 
+    public boolean setFileProtection(EnumSet<FileProtection> prot)
+        throws IOException, SecurityException
+    {
+        return fprot1(getPath(), FileProtection.bitmapOf(prot));
+    }
+
     /**
      * Returns {@code true} if the file denoted by this abstract
      * pathname is symbolic link.

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h?rev=777940&r1=777939&r2=777940&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_file.h Sat May 23 15:14:50 2009
@@ -42,7 +42,7 @@
 #define ACR_FT_UNKFILE  127    /**< a file of some other unknown type */
 
 /**
- * @defgroup apr_file_permissions File Permissions flags 
+ * @defgroup apr_file_permissions File Permissions flags
  * @{
  */
 
@@ -135,10 +135,28 @@
  * @param env JNI environment to use. If NULL no exception will be thrown
  *            if stat fails.
  * @param fname File name for which to get the type.
- * @return One of the ACR_FT_* types or -1 of error
+ * @return One of the ACR_FT_* types or -1 on error
  */
 ACR_DECLARE(int) ACR_FileTypeGet(JNIEnv *_E, const acr_pchar_t *fname);
 
+/** Set File protection mode
+ * @param env JNI environment to use. If NULL no exception will be thrown
+ *            if stat fails.
+ * @param fname File name for which to set the protection.
+ * @param prot Combination of ACR_FPROT_* flags.
+ * @return ACR_ERROR code on failure
+ */
+ACR_DECLARE(int) ACR_FileProtectionSet(JNIEnv *_E, acr_pchar_t *fname,
+                                       int prot);
+
+/** Get File protection mode
+ * @param env JNI environment to use. If NULL no exception will be thrown
+ *            if stat fails.
+ * @param fname File name for which to set the protection.
+ * @return Combination of ACR_FPROT_* flags or -1 on error.
+ */
+ACR_DECLARE(int) ACR_FileProtectionGet(JNIEnv *_E, acr_pchar_t *fname);
+
 /** Create new File object with FileType set.
  * @param env JNI environment to use. If NULL no exception will be thrown
  *            if stat fails.

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c?rev=777940&r1=777939&r2=777940&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/file.c Sat May 23 15:14:50 2009
@@ -91,12 +91,12 @@
          * include files, APR cannot report a good reason why the stat()
          * of the file failed; there are cases where it can fail even though
          * the file exists.  This opens holes in Apache, for example, because
-         * it becomes possible for someone to get a directory listing of a 
-         * directory even though there is an index (eg. index.html) file in 
-         * it.  If you do not have a problem with this, delete the above 
+         * it becomes possible for someone to get a directory listing of a
+         * directory even though there is an index (eg. index.html) file in
+         * it.  If you do not have a problem with this, delete the above
          * #error lines and start the compile again.  If you need to do this,
          * please submit a bug report to http://www.apache.org/bug_report.html
-         * letting us know that you needed to do this.  Please be sure to 
+         * letting us know that you needed to do this.  Please be sure to
          * include the operating system you are using.
          */
 #endif
@@ -288,6 +288,23 @@
     return -1;
 }
 
+ACR_DECLARE(int) ACR_FileProtectionSet(JNIEnv *_E, const char *fname, int prot)
+{
+    struct_stat info;
+
+    /* Always use a real target */
+    if (chown(fname, ACR_UnixPermsToMode(prot)) == 0) {
+        return 0;
+    }
+    else if (_E) {
+        if (errno == EACCES)
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+        else
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, errno);
+    }
+    return errno;
+}
+
 ACR_IO_EXPORT_DECLARE(int, File, fprot0)(ACR_JNISTDARGS, jstring pathname)
 {
     int prot = 0;
@@ -299,3 +316,20 @@
 
     return prot;
 }
+
+ACR_IO_EXPORT_DECLARE(jboolean, File, fprot1)(ACR_JNISTDARGS, jstring pathname,
+                                              jint prot)
+{
+    int rc = -1;
+
+    UNREFERENCED_O;
+
+    WITH_WSTR(pathname) {
+        rc = ACR_FileProtectionSet(_E, J2W(pathname), prot);
+    } END_WITH_WSTR(pathname);
+
+    if (rc)
+        return JNI_FALSE;
+    else
+        return JNI_TRUE;
+}

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=777940&r1=777939&r2=777940&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 Sat May 23 15:14:50 2009
@@ -358,6 +358,23 @@
     return (prot << scope);
 }
 
+static ACCESS_MASK convert_acc(int prot, 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
+     */
+    ACCESS_MASK acc = 0;
+    prot = (prot >> scope) & 0x0F;
+    if (prot & ACR_FPROT_WEXECUTE)
+        acc |= FILE_EXECUTE;
+    if (prot & ACR_FPROT_WWRITE)
+        acc |= FILE_WRITE_DATA;
+    if (prot & ACR_FPROT_WREAD)
+        acc |= FILE_READ_DATA;
+    return acc;
+}
+
 static int resolve_prot(PSID user, PSID group, PACL dacl)
 {
     TRUSTEE_W ident = { NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID };
@@ -405,16 +422,23 @@
     int protection = 0;
     PSID user = NULL, group = NULL;
     PACL dacl = NULL;
-    PSECURITY_DESCRIPTOR pdesc = NULL;
+    PSECURITY_DESCRIPTOR ppsd = NULL;
     int fix = 0;
     int rc;
 
     if (wcsncmp(fname, L"\\\\?\\", 4) == 0) {
         fname += 4;
         if (wcsncmp(fname, L"UNC\\", 4) == 0) {
+            /* TODO: Do not modify in fname in-place.
+             */
             fname += 2;
             *fname = L'\\';
         }
+        else if (wcsncmp(fname, L"UN\\\\", 4) == 0) {
+            /* Already modified in-place.
+             */
+            fname += 2;
+        }
     }
     rc = GetNamedSecurityInfoW(fname,
                                SE_FILE_OBJECT,
@@ -423,7 +447,7 @@
                                &group,
                                &dacl,
                                NULL,
-                               &pdesc);
+                               &ppsd);
     if (rc == ERROR_SUCCESS) {
         return resolve_prot(user, group, dacl);
     }
@@ -437,6 +461,137 @@
     return 0;
 }
 
+static PACL update_prot(PSID user, PSID group, PACL dacl, int prot)
+{
+    PACL eacl = NULL;
+    EXPLICIT_ACCESS_W eacc[3];
+    ACCESS_MASK acc;
+    TRUSTEE_W ident = { NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID };
+    int tc = 0;
+    DWORD rc;
+
+    /*
+     * This function is only invoked for WinNT,
+     * there is no reason for os_level testing here.
+     */
+    acc = convert_acc(prot, prot_scope_user);
+    if (user && acc) {
+        ZeroMemory(&eacc[tc], sizeof(EXPLICIT_ACCESS));
+        eacc[tc].Trustee = ident;
+        eacc[tc].Trustee.TrusteeType = TRUSTEE_IS_USER;
+        eacc[tc].Trustee.ptstrName = user;
+        eacc[tc].grfAccessPermissions = acc;
+        eacc[tc].grfAccessMode = SET_ACCESS;
+        eacc[tc].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+
+        ++tc;
+    }
+    /* 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.
+     */
+    acc = convert_acc(prot, prot_scope_group);
+    if (group && acc) {
+        ZeroMemory(&eacc[tc], sizeof(EXPLICIT_ACCESS));
+        eacc[tc].Trustee = ident;
+        eacc[tc].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
+        eacc[tc].Trustee.ptstrName = group;
+        eacc[tc].grfAccessPermissions = acc;
+        eacc[tc].grfAccessMode = SET_ACCESS;
+        eacc[tc].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+
+        ++tc;
+    }
+    acc = convert_acc(prot, prot_scope_world);
+    if (acr_everyone_sid && acc) {
+        ZeroMemory(&eacc[tc], sizeof(EXPLICIT_ACCESS));
+        eacc[tc].Trustee = ident;
+        eacc[tc].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+        eacc[tc].Trustee.ptstrName = acr_everyone_sid;
+        eacc[tc].grfAccessPermissions = acc;
+        eacc[tc].grfAccessMode = SET_ACCESS;
+        eacc[tc].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+
+        ++tc;
+    }
+    rc = SetEntriesInAclW(tc, &eacc[0], dacl, &eacl);
+    if (rc != ERROR_SUCCESS) {
+        SetLastError(rc);
+        return NULL;
+    }
+    else {
+        return eacl;
+    }
+}
+
+ACR_DECLARE(int) ACR_FileProtectionSet(JNIEnv *_E, wchar_t *fname, int prot)
+{
+    int protection = 0;
+    PSID user = NULL, group = NULL;
+    PACL dacl = NULL;
+    PACL eacl = NULL;
+    PSECURITY_DESCRIPTOR ppsd = NULL;
+    int fix = 0;
+    int rc;
+
+    if (wcsncmp(fname, L"\\\\?\\", 4) == 0) {
+        fname += 4;
+        if (wcsncmp(fname, L"UNC\\", 4) == 0) {
+            fname += 2;
+            *fname = L'\\';
+        }
+        else if (wcsncmp(fname, L"UN\\\\", 4) == 0) {
+            /* Already modified in-place.
+             */
+            fname += 2;
+        }
+    }
+    rc = GetNamedSecurityInfoW(fname,
+                               SE_FILE_OBJECT,
+                               OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+                               &user,
+                               &group,
+                               &dacl,
+                               NULL,
+                               &ppsd);
+    if (rc != ERROR_SUCCESS) {
+        goto failed;
+    }
+
+    eacl = update_prot(user, group, dacl, prot);
+    if (!eacl) {
+        rc = GetLastError();
+        goto failed;
+    }
+    rc = SetNamedSecurityInfoW(fname,
+                               SE_FILE_OBJECT,
+                               DACL_SECURITY_INFORMATION,
+                               NULL,
+                               NULL,
+                               eacl,
+                               NULL);
+
+    if (rc != ERROR_SUCCESS) {
+        goto failed;
+    }
+    LocalFree((HLOCAL)eacl);
+    return 0;
+
+failed:
+    rc = ACR_FROM_OS_ERROR(rc);
+    if (_E) {
+        if  (ACR_STATUS_IS_EACCES(rc))
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+        else
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+    }
+    if (eacl) {
+        LocalFree((HLOCAL)eacl);
+    }
+    return rc;
+}
+
 ACR_IO_EXPORT_DECLARE(int, File, fprot0)(ACR_JNISTDARGS, jstring pathname)
 {
     int prot = 0;
@@ -448,3 +603,20 @@
 
     return prot;
 }
+
+ACR_IO_EXPORT_DECLARE(jboolean, File, fprot1)(ACR_JNISTDARGS, jstring pathname,
+                                              jint prot)
+{
+    int rc = -1;
+
+    UNREFERENCED_O;
+
+    WITH_WSTR(pathname) {
+        rc = ACR_FileProtectionSet(_E, J2W(pathname), prot);
+    } END_WITH_WSTR(pathname);
+
+    if (rc)
+        return JNI_FALSE;
+    else
+        return JNI_TRUE;
+}

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=777940&r1=777939&r2=777940&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 Sat May 23 15:14:50 2009
@@ -99,10 +99,10 @@
             File second = new File("foo");
             File link2 = second.createSymbolicLink("bar");
             assertEquals("Name", "bar", link2.getPath());
-    
+
             symlnk.delete();
         } catch (UnsupportedOperationException u) {
-            // fail("Unsupported Operating system");            
+            // fail("Unsupported Operating system");
         }
 
     }
@@ -121,12 +121,12 @@
                 File link2 = second.createSymbolicLink("bar");
                 fail("Exception not thrown");
             } catch (Exception ex) {
-                // This is expected 
-            } finally {        
+                // This is expected
+            } finally {
                 symlnk.delete();
             }
         } catch (UnsupportedOperationException u) {
-            // fail("Unsupported Operating system");            
+            // fail("Unsupported Operating system");
         }
     }
 
@@ -141,10 +141,10 @@
             assertEquals("Type", FileType.LNK, t);
             File target = symlnk.getTargetFile();
             assertEquals("Target", source.getPath(), target.getPath());
-    
+
             symlnk.delete();
         } catch (UnsupportedOperationException u) {
-            // fail("Unsupported Operating system");            
+            // fail("Unsupported Operating system");
         }
 
     }
@@ -167,7 +167,7 @@
         }
     }
 
-    public void testProtection()
+    public void testGetProtection()
         throws Exception
     {
         File f = new File("ffoo");
@@ -176,5 +176,20 @@
         System.out.println("Protection " + fp);
         assertTrue("UWRITE", fp.contains(FileProtection.UWRITE));
         f.delete();
-    }    
+    }
+
+    public void testSetProtection()
+        throws Exception
+    {
+        File f = new File("ffoo");
+        f.createNewFile();
+        EnumSet <FileProtection> fp = f.getFileProtection();
+        System.out.println("Org Protection " + fp);
+        f.setFileProtection(EnumSet.of(FileProtection.GWRITE));
+        EnumSet <FileProtection> np = f.getFileProtection();
+        System.out.println("Set Protection " + np);
+        assertTrue("GWRITE", np.contains(FileProtection.GWRITE));
+        f.delete();
+    }
+
 }