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