From 5ce1658269d23c7c7289f205a72345abd1d7d1b2 Mon Sep 17 00:00:00 2001 From: Shawn Garner Date: Tue, 21 Jan 2014 04:53:49 +0000 Subject: [PATCH 1/4] Added Advapi32Util accessCheck method to verify file permissions --- .../com/sun/jna/platform/win32/Advapi32.java | 29 +++++ .../sun/jna/platform/win32/Advapi32Util.java | 117 ++++++++++++++++++ .../src/com/sun/jna/platform/win32/WinNT.java | 59 +++++++++ .../jna/platform/win32/Advapi32UtilTest.java | 17 +++ 4 files changed, 222 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java index 5c05ccd820..6c7293142b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java @@ -1523,4 +1523,33 @@ public boolean GetFileSecurity(WString lpFileName, int RequestedInformation, Pointer pointer, int nLength, IntByReference lpnLengthNeeded); + + /** + * Applies the given mapping of generic access rights to the given access mask. + * @param AccessMask [in, out] A pointer to an access mask. + * @param GenericMapping [in] A pointer to a GENERIC_MAPPING structure specifying a mapping of generic access types to specific and standard access types. + */ + public void MapGenericMask(WinDef.DWORDByReference AccessMask, WinNT.GENERIC_MAPPING GenericMapping); + + + /** + * Check if the if the security descriptor grants access to the given client token. + * + * @param pSecurityDescriptor [in] A pointer to a SECURITY_DESCRIPTOR structure against which access is checked. + * @param ClientToken [in] A handle to an impersonation token that represents the client that is attempting to gain access. The handle must have TOKEN_QUERY access to the token; otherwise, the function fails with ERROR_ACCESS_DENIED. + * @param DesiredAccess [in] Access mask that specifies the access rights to check. This mask must have been mapped by the MapGenericMask function to contain no generic access rights.
+ * If this parameter is MAXIMUM_ALLOWED, the function sets the GrantedAccess access mask to indicate the maximum access rights the security descriptor allows the client. + * @param GenericMapping [in] A pointer to the GENERIC_MAPPING structure associated with the object for which access is being checked. + * @param PrivilegeSet [out, optional] A pointer to a PRIVILEGE_SET structure that receives the privileges used to perform the access validation. If no privileges were used, the function sets the PrivilegeCount member to zero. + * @param PrivilegeSetLength [in, out] Specifies the size, in bytes, of the buffer pointed to by the PrivilegeSet parameter. + * @param GrantedAccess [out] A pointer to an access mask that receives the granted access rights. If AccessStatus is set to FALSE, the function sets the access mask to zero. If the function fails, it does not set the access mask. + * @param AccessStatus [out] A pointer to a variable that receives the results of the access check. If the security descriptor allows the requested access rights to the client identified by the access token, AccessStatus is set to TRUE. Otherwise, AccessStatus is set to FALSE, and you can call GetLastError to get extended error information. + * @return true on success; false on failure (use GetLastError to get extended error information) + */ + public boolean AccessCheck(Pointer pSecurityDescriptor, + HANDLE ClientToken, WinDef.DWORD DesiredAccess, + WinNT.GENERIC_MAPPING GenericMapping, + WinNT.PRIVILEGE_SET PrivilegeSet, + WinDef.DWORDByReference PrivilegeSetLength, + WinDef.DWORDByReference GrantedAccess, WinDef.BOOLByReference AccessStatus); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java index 10d017ec4a..0892cecfa6 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java @@ -12,6 +12,7 @@ */ package com.sun.jna.platform.win32; +import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -81,6 +82,7 @@ public static class Account { public String fqn; } + /** * Retrieves the name of the user associated with the current thread. * @@ -2062,4 +2064,119 @@ public static ACCESS_ACEStructure[] getFileSecurity(String fileName, } return aceStructures; } + + public static enum AccessCheckPermission { + READ(WinNT.GENERIC_READ), + WRITE(WinNT.GENERIC_WRITE), + EXECUTE(WinNT.GENERIC_EXECUTE); + + final int code; + + AccessCheckPermission(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + } + + + private static Memory getSecurityDescriptorForFile(final String absoluteFilePath) { + final int infoType = WinNT.OWNER_SECURITY_INFORMATION | WinNT.GROUP_SECURITY_INFORMATION | + WinNT.DACL_SECURITY_INFORMATION; + + final IntByReference lpnSize = new IntByReference(); + boolean succeeded = Advapi32.INSTANCE.GetFileSecurity( + new WString(absoluteFilePath), + infoType, + null, + 0, lpnSize); + + if (!succeeded) { + final int lastError = Kernel32.INSTANCE.GetLastError(); + if (W32Errors.ERROR_INSUFFICIENT_BUFFER != lastError) { + throw new Win32Exception(lastError); + } + } + + final int nLength = lpnSize.getValue(); + final Memory securityDescriptorMemoryPointer = new Memory(nLength); + succeeded = Advapi32.INSTANCE.GetFileSecurity(new WString( + absoluteFilePath), infoType, securityDescriptorMemoryPointer, nLength, lpnSize); + + if (!succeeded) { + securityDescriptorMemoryPointer.clear(); + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + return securityDescriptorMemoryPointer; + } + + /** + * Checks if the current process has the given permission for the file. + * @param file the file to check + * @param permissionToCheck the permission to check for the file + * @return true if has access, otherwise false + */ + public static boolean accessCheck(File file, AccessCheckPermission permissionToCheck) { + boolean hasAccess = false; + final Memory securityDescriptorMemoryPointer = getSecurityDescriptorForFile(file.getAbsolutePath().replaceAll("/", "\\")); + + HANDLEByReference openedAccessToken = null; + final HANDLEByReference duplicatedToken = new HANDLEByReference(); + try{ + openedAccessToken = new HANDLEByReference(); + + final int desireAccess = WinNT.TOKEN_IMPERSONATE | WinNT.TOKEN_QUERY | WinNT.TOKEN_DUPLICATE | WinNT.STANDARD_RIGHTS_READ; + if(!Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), desireAccess, openedAccessToken)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + if(!Advapi32.INSTANCE.DuplicateToken(openedAccessToken.getValue(), WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, duplicatedToken)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + mapping.genericRead = new WinDef.DWORD(WinNT.FILE_GENERIC_READ); + mapping.genericWrite = new WinDef.DWORD(WinNT.FILE_GENERIC_WRITE); + mapping.genericExecute = new WinDef.DWORD(WinNT.FILE_GENERIC_EXECUTE); + mapping.genericAll = new WinDef.DWORD(WinNT.FILE_ALL_ACCESS); + + final WinDef.DWORDByReference rights = new WinDef.DWORDByReference(new WinDef.DWORD(permissionToCheck.getCode())); + Advapi32.INSTANCE.MapGenericMask(rights, mapping); + + final WinNT.PRIVILEGE_SET privileges = new WinNT.PRIVILEGE_SET(1); + privileges.PrivilegeCount = new WinDef.DWORD(0); + final WinNT.DWORDByReference privilegeLength = new WinDef.DWORDByReference(new WinDef.DWORD(privileges.size())); + + final WinDef.DWORDByReference grantedAccess = new WinDef.DWORDByReference(); + final WinDef.BOOLByReference result = new WinDef.BOOLByReference(); + if(!Advapi32.INSTANCE.AccessCheck(securityDescriptorMemoryPointer, + duplicatedToken.getValue(), + rights.getValue(), + mapping, + privileges, privilegeLength, grantedAccess, result)) { + throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); + } + + hasAccess = result.getValue().booleanValue(); + + } finally { + + if(openedAccessToken != null && openedAccessToken.getValue() != null) { + Kernel32.INSTANCE.CloseHandle(openedAccessToken.getValue()); + } + + if(duplicatedToken != null && duplicatedToken.getValue() != null) { + Kernel32.INSTANCE.CloseHandle(duplicatedToken.getValue()); + } + + if(securityDescriptorMemoryPointer != null) { + securityDescriptorMemoryPointer.clear(); + } + } + + return hasAccess; + } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index 8c593b3044..df3a01f2ed 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -453,6 +453,46 @@ public SID_AND_ATTRIBUTES[] getGroups() { } } + /** + * Specifies a set of privileges.
+ * It is also used to indicate which, if any, privileges are held by a user or group requesting access to an object. + */ + public static class PRIVILEGE_SET extends Structure { + public DWORD PrivilegeCount; + public DWORD Control; + public LUID_AND_ATTRIBUTES Privileges[]; + + @Override + protected List getFieldOrder() { + return Arrays.asList("PrivilegeCount", "Control", "Privileges"); + } + + public PRIVILEGE_SET() { + this(0); + } + /** + * @param nbOfPrivileges + * Desired size of the Privileges array + */ + public PRIVILEGE_SET(int nbOfPrivileges) { + PrivilegeCount = new DWORD(nbOfPrivileges); + if(nbOfPrivileges > 0) { + Privileges = new LUID_AND_ATTRIBUTES[nbOfPrivileges]; + } + } + + /** Initialize a TOKEN_PRIVILEGES instance from initialized memory. */ + public PRIVILEGE_SET(Pointer p) { + super(p); + final int count = p.getInt(0); + PrivilegeCount = new DWORD(count); + if(count > 0) { + Privileges = new LUID_AND_ATTRIBUTES[count]; + } + read(); + } + } + /** * The TOKEN_PRIVILEGES structure contains information about a set of * privileges for an access token. @@ -2176,6 +2216,25 @@ void callback(int errorCode, int nBytesTransferred, WinBase.OVERLAPPED overlapped); } + + /** + * Defines the mapping of generic access rights to specific and standard access rights for an object + */ + public static class GENERIC_MAPPING extends Structure { + public static class ByReference extends GENERIC_MAPPING implements Structure.ByReference { + } + + public DWORD genericRead; + public DWORD genericWrite; + public DWORD genericExecute; + public DWORD genericAll; + + @Override + protected List getFieldOrder() { + return Arrays.asList("genericRead", "genericWrite", "genericExecute", "genericAll"); + } + } + /** * Describes the relationship between the specified processor set. This structure is used with the * {@link Kernel32#GetLogicalProcessorInformation} function. diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java index b97c0b52df..835c409a2e 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java @@ -12,6 +12,7 @@ */ package com.sun.jna.platform.win32; +import java.io.File; import java.util.Map; import java.util.TreeMap; @@ -55,6 +56,22 @@ public static void main(String[] args) { System.out.println(" Name: " + accountBySid.name); System.out.println(" Domain: " + accountBySid.domain); } + + public void testReadAccess() { + final boolean access = Advapi32Util.accessCheck(new File(System.getProperty("java.io.tmpdir")), Advapi32Util.AccessCheckPermission.READ); + assertTrue(access); + } + + public void testWriteAccess() { + final boolean access = Advapi32Util.accessCheck(new File(System.getProperty("java.io.tmpdir")), Advapi32Util.AccessCheckPermission.WRITE); + assertTrue(access); + } + + + public void testExecuteAccess() { + final boolean access = Advapi32Util.accessCheck(new File(System.getProperty("java.io.tmpdir")), Advapi32Util.AccessCheckPermission.EXECUTE); + assertTrue(access); + } public void testGetUsername() { String username = Advapi32Util.getUserName(); From 3f23dc3ffb91c3e27ec1d2f7ab4c4e0a2b4efb7f Mon Sep 17 00:00:00 2001 From: Shawn Garner Date: Wed, 22 Jan 2014 02:35:26 +0000 Subject: [PATCH 2/4] Addressed code review items from pull request --- CHANGES.md | 1 + .../com/sun/jna/platform/win32/Advapi32.java | 18 ++++-- .../sun/jna/platform/win32/Advapi32Util.java | 46 ++++++++------- .../sun/jna/platform/win32/Advapi32Test.java | 59 +++++++++++++++++++ 4 files changed, 98 insertions(+), 26 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index c4310c539e..4e8344021f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,6 +18,7 @@ Features * [#250](https://github.com/twall/jna/pull/250): Added `com.sun.jna.platform.win32.Kernel32.GetPrivateProfileSection`, `GetPrivateProfileSectionNames` and `WritePrivateProfileSection` and corresponding `Kernel32Util` helpers - [@quipsy-karg](https://github.com/quipsy-karg). * [#287](https://github.com/twall/jna/pull/287): Added `DBTF_MEDIA` and `DBTF_NET` to `com.sun.jna.platform.win32.DBT` - [@daifei4321](https://github.com/daifei4321). * [#295](https://github.com/twall/jna/pull/295): Added `com.sun.jna.platform.win32.Kernel32.ResetEvent` - [@manithree](https://github.com/manithree). +* [#301](https://github.com/twall/jna/pull/301): Added `com.sun.jna.platform.win32.Advapi32Util.accessCheck` and supporting classes/methods to verify file permissions - [@BusyByte] (https://github.com/BusyByte/jna). Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java index 6c7293142b..d34c06dc4b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java @@ -32,6 +32,12 @@ import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; +import static com.sun.jna.platform.win32.WinDef.BOOLByReference; +import static com.sun.jna.platform.win32.WinDef.DWORD; +import static com.sun.jna.platform.win32.WinDef.DWORDByReference; +import static com.sun.jna.platform.win32.WinNT.GENERIC_MAPPING; +import static com.sun.jna.platform.win32.WinNT.PRIVILEGE_SET; + /** * Advapi32.dll Interface. * @@ -1529,7 +1535,7 @@ public boolean GetFileSecurity(WString lpFileName, * @param AccessMask [in, out] A pointer to an access mask. * @param GenericMapping [in] A pointer to a GENERIC_MAPPING structure specifying a mapping of generic access types to specific and standard access types. */ - public void MapGenericMask(WinDef.DWORDByReference AccessMask, WinNT.GENERIC_MAPPING GenericMapping); + public void MapGenericMask(DWORDByReference AccessMask, GENERIC_MAPPING GenericMapping); /** @@ -1547,9 +1553,9 @@ public boolean GetFileSecurity(WString lpFileName, * @return true on success; false on failure (use GetLastError to get extended error information) */ public boolean AccessCheck(Pointer pSecurityDescriptor, - HANDLE ClientToken, WinDef.DWORD DesiredAccess, - WinNT.GENERIC_MAPPING GenericMapping, - WinNT.PRIVILEGE_SET PrivilegeSet, - WinDef.DWORDByReference PrivilegeSetLength, - WinDef.DWORDByReference GrantedAccess, WinDef.BOOLByReference AccessStatus); + HANDLE ClientToken, DWORD DesiredAccess, + GENERIC_MAPPING GenericMapping, + PRIVILEGE_SET PrivilegeSet, + DWORDByReference PrivilegeSetLength, + DWORDByReference GrantedAccess, BOOLByReference AccessStatus); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java index 0892cecfa6..c28e348c24 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java @@ -41,6 +41,12 @@ import com.sun.jna.ptr.LongByReference; import com.sun.jna.ptr.PointerByReference; +import static com.sun.jna.platform.win32.WinDef.BOOLByReference; +import static com.sun.jna.platform.win32.WinDef.DWORD; +import static com.sun.jna.platform.win32.WinDef.DWORDByReference; +import static com.sun.jna.platform.win32.WinNT.*; + + /** * Advapi32 utility API. * @@ -432,14 +438,14 @@ public static Account[] getCurrentUserGroups() { // open thread or process token HANDLE threadHandle = Kernel32.INSTANCE.GetCurrentThread(); if (!Advapi32.INSTANCE.OpenThreadToken(threadHandle, - WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, true, phToken)) { + TOKEN_DUPLICATE | TOKEN_QUERY, true, phToken)) { if (W32Errors.ERROR_NO_TOKEN != Kernel32.INSTANCE .GetLastError()) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } HANDLE processHandle = Kernel32.INSTANCE.GetCurrentProcess(); if (!Advapi32.INSTANCE.OpenProcessToken(processHandle, - WinNT.TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, phToken)) { + TOKEN_DUPLICATE | TOKEN_QUERY, phToken)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } } @@ -2066,9 +2072,9 @@ public static ACCESS_ACEStructure[] getFileSecurity(String fileName, } public static enum AccessCheckPermission { - READ(WinNT.GENERIC_READ), - WRITE(WinNT.GENERIC_WRITE), - EXECUTE(WinNT.GENERIC_EXECUTE); + READ(GENERIC_READ), + WRITE(GENERIC_WRITE), + EXECUTE(GENERIC_EXECUTE); final int code; @@ -2083,8 +2089,8 @@ public int getCode() { private static Memory getSecurityDescriptorForFile(final String absoluteFilePath) { - final int infoType = WinNT.OWNER_SECURITY_INFORMATION | WinNT.GROUP_SECURITY_INFORMATION | - WinNT.DACL_SECURITY_INFORMATION; + final int infoType = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION; final IntByReference lpnSize = new IntByReference(); boolean succeeded = Advapi32.INSTANCE.GetFileSecurity( @@ -2128,30 +2134,30 @@ public static boolean accessCheck(File file, AccessCheckPermission permissionToC try{ openedAccessToken = new HANDLEByReference(); - final int desireAccess = WinNT.TOKEN_IMPERSONATE | WinNT.TOKEN_QUERY | WinNT.TOKEN_DUPLICATE | WinNT.STANDARD_RIGHTS_READ; + final int desireAccess = TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE | STANDARD_RIGHTS_READ; if(!Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), desireAccess, openedAccessToken)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - if(!Advapi32.INSTANCE.DuplicateToken(openedAccessToken.getValue(), WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, duplicatedToken)) { + if(!Advapi32.INSTANCE.DuplicateToken(openedAccessToken.getValue(), SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, duplicatedToken)) { throw new Win32Exception(Kernel32.INSTANCE.GetLastError()); } - final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); - mapping.genericRead = new WinDef.DWORD(WinNT.FILE_GENERIC_READ); - mapping.genericWrite = new WinDef.DWORD(WinNT.FILE_GENERIC_WRITE); - mapping.genericExecute = new WinDef.DWORD(WinNT.FILE_GENERIC_EXECUTE); - mapping.genericAll = new WinDef.DWORD(WinNT.FILE_ALL_ACCESS); + final GENERIC_MAPPING mapping = new GENERIC_MAPPING(); + mapping.genericRead = new DWORD(FILE_GENERIC_READ); + mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); + mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); + mapping.genericAll = new DWORD(FILE_ALL_ACCESS); - final WinDef.DWORDByReference rights = new WinDef.DWORDByReference(new WinDef.DWORD(permissionToCheck.getCode())); + final DWORDByReference rights = new DWORDByReference(new DWORD(permissionToCheck.getCode())); Advapi32.INSTANCE.MapGenericMask(rights, mapping); - final WinNT.PRIVILEGE_SET privileges = new WinNT.PRIVILEGE_SET(1); - privileges.PrivilegeCount = new WinDef.DWORD(0); - final WinNT.DWORDByReference privilegeLength = new WinDef.DWORDByReference(new WinDef.DWORD(privileges.size())); + final PRIVILEGE_SET privileges = new PRIVILEGE_SET(1); + privileges.PrivilegeCount = new DWORD(0); + final DWORDByReference privilegeLength = new DWORDByReference(new DWORD(privileges.size())); - final WinDef.DWORDByReference grantedAccess = new WinDef.DWORDByReference(); - final WinDef.BOOLByReference result = new WinDef.BOOLByReference(); + final DWORDByReference grantedAccess = new DWORDByReference(); + final BOOLByReference result = new BOOLByReference(); if(!Advapi32.INSTANCE.AccessCheck(securityDescriptorMemoryPointer, duplicatedToken.getValue(), rights.getValue(), diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java index 229bf75e6a..d96f63be0a 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java @@ -41,6 +41,8 @@ import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; +import static com.sun.jna.platform.win32.WinNT.*; + /** * @author dblock[at]dblock[dot]org */ @@ -826,4 +828,61 @@ public void testImpersonateSelf() { assertTrue(Advapi32.INSTANCE.ImpersonateSelf(WinNT.SECURITY_IMPERSONATION_LEVEL.SecurityAnonymous)); assertTrue(Advapi32.INSTANCE.RevertToSelf()); } + + public void testMapGenericReadMask() { + final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + mapping.genericRead = new DWORD(FILE_GENERIC_READ); + mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); + mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); + mapping.genericAll = new DWORD(FILE_ALL_ACCESS); + + final DWORDByReference rights = new DWORDByReference(new DWORD(GENERIC_READ)); + Advapi32.INSTANCE.MapGenericMask(rights, mapping); + + assertEquals(FILE_GENERIC_READ, rights.getValue().intValue()); + assertTrue(GENERIC_READ != (rights.getValue().intValue() & GENERIC_READ)); + } + + public void testMapGenericWriteMask() { + final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + mapping.genericRead = new DWORD(FILE_GENERIC_READ); + mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); + mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); + mapping.genericAll = new DWORD(FILE_ALL_ACCESS); + + final DWORDByReference rights = new DWORDByReference(new DWORD(GENERIC_WRITE)); + Advapi32.INSTANCE.MapGenericMask(rights, mapping); + + assertEquals(FILE_GENERIC_WRITE, rights.getValue().intValue()); + assertTrue(GENERIC_WRITE != (rights.getValue().intValue() & GENERIC_WRITE)); + } + + public void testMapGenericExecuteMask() { + final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + mapping.genericRead = new DWORD(FILE_GENERIC_READ); + mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); + mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); + mapping.genericAll = new DWORD(FILE_ALL_ACCESS); + + final DWORDByReference rights = new DWORDByReference(new DWORD(GENERIC_EXECUTE)); + Advapi32.INSTANCE.MapGenericMask(rights, mapping); + + assertEquals(FILE_GENERIC_EXECUTE, rights.getValue().intValue()); + assertTrue(GENERIC_EXECUTE != (rights.getValue().intValue() & GENERIC_EXECUTE)); + } + + public void testMapGenericAllMask() { + final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + mapping.genericRead = new DWORD(FILE_GENERIC_READ); + mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); + mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); + mapping.genericAll = new DWORD(FILE_ALL_ACCESS); + + final DWORDByReference rights = new DWORDByReference(new DWORD(GENERIC_ALL)); + Advapi32.INSTANCE.MapGenericMask(rights, mapping); + + assertEquals(FILE_ALL_ACCESS, rights.getValue().intValue()); + assertTrue(GENERIC_ALL != (rights.getValue().intValue() & GENERIC_ALL)); + } + } From d84910a762eaab40e1732ef3dda0917785bdbb4c Mon Sep 17 00:00:00 2001 From: pair9 Date: Wed, 22 Jan 2014 13:24:20 -0600 Subject: [PATCH 3/4] Added test for com.sun.jna.platform.win32.Advapi32.AccessCheck and updated changelog markup --- CHANGES.md | 2 +- .../sun/jna/platform/win32/Advapi32Test.java | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 4e8344021f..afe073aeb8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,7 +18,7 @@ Features * [#250](https://github.com/twall/jna/pull/250): Added `com.sun.jna.platform.win32.Kernel32.GetPrivateProfileSection`, `GetPrivateProfileSectionNames` and `WritePrivateProfileSection` and corresponding `Kernel32Util` helpers - [@quipsy-karg](https://github.com/quipsy-karg). * [#287](https://github.com/twall/jna/pull/287): Added `DBTF_MEDIA` and `DBTF_NET` to `com.sun.jna.platform.win32.DBT` - [@daifei4321](https://github.com/daifei4321). * [#295](https://github.com/twall/jna/pull/295): Added `com.sun.jna.platform.win32.Kernel32.ResetEvent` - [@manithree](https://github.com/manithree). -* [#301](https://github.com/twall/jna/pull/301): Added `com.sun.jna.platform.win32.Advapi32Util.accessCheck` and supporting classes/methods to verify file permissions - [@BusyByte] (https://github.com/BusyByte/jna). +* [#301](https://github.com/twall/jna/pull/301): Added `accessCheck` to `com.sun.jna.platform.win32.Advapi32Util`, `MapGenericMask` and `AccessCheck` to `com.sun.jna.platform.win32.Advapi32`, `PRIVILEGE_SET` and `GENERIC_MAPPING` to `com.sun.jna.platform.win32.WinNT` - [@BusyByte](https://github.com/BusyByte). Bug Fixes --------- diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java index d96f63be0a..bc209ac8bb 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java @@ -885,4 +885,25 @@ public void testMapGenericAllMask() { assertTrue(GENERIC_ALL != (rights.getValue().intValue() & GENERIC_ALL)); } + public void testAccessCheck() { + final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + mapping.genericRead = new DWORD(FILE_GENERIC_READ); + mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); + mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); + mapping.genericAll = new DWORD(FILE_ALL_ACCESS); + final Memory securityDescriptorMemoryPointer = new Memory(1); + + final PRIVILEGE_SET privileges = new PRIVILEGE_SET(1); + privileges.PrivilegeCount = new DWORD(0); + final DWORDByReference privilegeLength = new DWORDByReference(new DWORD(privileges.size())); + final DWORDByReference grantedAccess = new DWORDByReference(); + final BOOLByReference result = new BOOLByReference(); + + final boolean status = Advapi32.INSTANCE.AccessCheck(securityDescriptorMemoryPointer, null, new DWORD(FILE_GENERIC_READ), mapping, privileges, privilegeLength, grantedAccess, result); + assertFalse(status); + assertFalse(result.getValue().booleanValue()); + + assertEquals("The handle is invalid.", Kernel32Util.formatMessage(W32Errors.HRESULT_FROM_WIN32(Kernel32.INSTANCE.GetLastError()))); + } + } From e3aa9cd1a21f8f107c5293df392b4cdaffc29e19 Mon Sep 17 00:00:00 2001 From: pair9 Date: Wed, 22 Jan 2014 16:24:12 -0600 Subject: [PATCH 4/4] Changed Advapi32Test.testAccessCheck to work on non-US-English systems and general cleanup --- .../sun/jna/platform/win32/Advapi32Test.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java index bc209ac8bb..c144ee11de 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Advapi32Test.java @@ -830,7 +830,7 @@ public void testImpersonateSelf() { } public void testMapGenericReadMask() { - final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + final GENERIC_MAPPING mapping = new GENERIC_MAPPING(); mapping.genericRead = new DWORD(FILE_GENERIC_READ); mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); @@ -840,11 +840,11 @@ public void testMapGenericReadMask() { Advapi32.INSTANCE.MapGenericMask(rights, mapping); assertEquals(FILE_GENERIC_READ, rights.getValue().intValue()); - assertTrue(GENERIC_READ != (rights.getValue().intValue() & GENERIC_READ)); + assertTrue(GENERIC_READ != (rights.getValue().intValue() & GENERIC_READ)); } public void testMapGenericWriteMask() { - final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + final GENERIC_MAPPING mapping = new GENERIC_MAPPING(); mapping.genericRead = new DWORD(FILE_GENERIC_READ); mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); @@ -854,11 +854,11 @@ public void testMapGenericWriteMask() { Advapi32.INSTANCE.MapGenericMask(rights, mapping); assertEquals(FILE_GENERIC_WRITE, rights.getValue().intValue()); - assertTrue(GENERIC_WRITE != (rights.getValue().intValue() & GENERIC_WRITE)); + assertTrue(GENERIC_WRITE != (rights.getValue().intValue() & GENERIC_WRITE)); } public void testMapGenericExecuteMask() { - final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + final GENERIC_MAPPING mapping = new GENERIC_MAPPING(); mapping.genericRead = new DWORD(FILE_GENERIC_READ); mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); @@ -868,11 +868,11 @@ public void testMapGenericExecuteMask() { Advapi32.INSTANCE.MapGenericMask(rights, mapping); assertEquals(FILE_GENERIC_EXECUTE, rights.getValue().intValue()); - assertTrue(GENERIC_EXECUTE != (rights.getValue().intValue() & GENERIC_EXECUTE)); + assertTrue(GENERIC_EXECUTE != (rights.getValue().intValue() & GENERIC_EXECUTE)); } public void testMapGenericAllMask() { - final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + final GENERIC_MAPPING mapping = new GENERIC_MAPPING(); mapping.genericRead = new DWORD(FILE_GENERIC_READ); mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); @@ -886,7 +886,7 @@ public void testMapGenericAllMask() { } public void testAccessCheck() { - final WinNT.GENERIC_MAPPING mapping = new WinNT.GENERIC_MAPPING(); + final GENERIC_MAPPING mapping = new GENERIC_MAPPING(); mapping.genericRead = new DWORD(FILE_GENERIC_READ); mapping.genericWrite = new DWORD(FILE_GENERIC_WRITE); mapping.genericExecute = new DWORD(FILE_GENERIC_EXECUTE); @@ -903,7 +903,7 @@ public void testAccessCheck() { assertFalse(status); assertFalse(result.getValue().booleanValue()); - assertEquals("The handle is invalid.", Kernel32Util.formatMessage(W32Errors.HRESULT_FROM_WIN32(Kernel32.INSTANCE.GetLastError()))); + assertEquals(WinError.ERROR_INVALID_HANDLE, Kernel32.INSTANCE.GetLastError()); } }