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