Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding security functions and RtlNtStatusToDosError to NtDll #738

Merged
merged 10 commits into from
Dec 12, 2016
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ Features
* [#689](https://github.com/java-native-access/jna/pull/689): Add `GetProcAddress(HMODULE, int)` to `com.sun.jna.platform.win32.Kernel32` - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#723](https://github.com/java-native-access/jna/pull/723): Added `com.sun.jna.platform.win32.Wevtapi` and `com.sun.jna.platform.win32.Winevt` - [@sakamotodesu](https://github.com/sakamotodesu).
* [#720](https://github.com/java-native-access/jna/issues/720): Added `SetThreadExecutionState` to `com.sun.jna.platform.win32.Kernel32` - [@matthiasblaesing](https://github.com/matthiasblaesing).
* [#738](https://github.com/java-native-access/jna/pull/738): Added `GetSecurityDescriptorOwner`, `SetSecurityDescriptorOwner`, `GetSecurityDescriptorGroup`, `SetSecurityDescriptorGroup`, `GetSecurityDescriptorControl`, `SetSecurityDescriptorControl`, `GetSecurityDescriptorDacl`, `SetSecurityDescriptorDacl`, `MakeSelfRelativeSD`, `MakeAbsoluteSD`, `EqualSid`, `InitializeSecurityDescriptor`, `InitializeAcl`, `AddAce`, `AddAccessAllowedAce`, `AddAccessAllowedAceEx`, and `GetAce` to `com.sun.jna.platform.win32.Advapi32 - [@amarcionek](https://github.com/amarcionek).
* [#738](https://github.com/java-native-access/jna/pull/738): Added `RtlNtStatusToDosError` to `com.sun.jna.platform.win32.NtDll - [@amarcionek](https://github.com/amarcionek).
* [#732](https://github.com/java-native-access/jna/pull/732): Added `com.sun.jna.platform.win32.WinioctlUtil` for help in determining FSCTL_* codes - [@amarcionek](https://github.com/amarcionek).
* [#732](https://github.com/java-native-access/jna/pull/732): Added `com.sun.jna.platform.win32.Ntifs` with Reparse Point structures and defines - [@amarcionek](https://github.com/amarcionek).
* [#732](https://github.com/java-native-access/jna/pull/732): Added initialization of FILETIME from LARGE_INTEGER - [@amarcionek](https://github.com/amarcionek).
Expand Down
384 changes: 384 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/Advapi32.java

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGByReference;
import com.sun.jna.platform.win32.WinNT.ACCESS_ACEStructure;
import com.sun.jna.platform.win32.WinNT.ACCESS_ALLOWED_ACE;
import com.sun.jna.platform.win32.WinNT.ACL;
import com.sun.jna.platform.win32.WinNT.EVENTLOGRECORD;
import com.sun.jna.platform.win32.WinNT.GENERIC_MAPPING;
Expand Down Expand Up @@ -380,7 +381,27 @@ public static boolean isWellKnownSid(byte[] sidBytes, int wellKnownSidType) {
return Advapi32.INSTANCE.IsWellKnownSid(pSID, wellKnownSidType);
}

/**
* Align cbAcl on a DWORD
* @param cbAcl size to align
* @return the aligned size
*/
public static int alignOnDWORD(int cbAcl) {
return (cbAcl + (DWORD.SIZE - 1)) & 0xfffffffc;
}

/**
* Helper function to calculate the size of an ACE for a given PSID size
* @param sidLength length of the sid
* @return size of the ACE
*/
public static int getAceSize(int sidLength) {
return Native.getNativeSize(ACCESS_ALLOWED_ACE.class, null)
+ sidLength
- DWORD.SIZE;
}

/**
* Get an account name from a string SID on the local machine.
*
* @param sidString
Expand Down
9 changes: 9 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/NTStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,14 @@ public interface NTStatus {
// STATUS_ABANDONED_WAIT_63
//
int STATUS_ABANDONED_WAIT_63 = 0x000000BF;

//
// MessageId: STATUS_INVALID_OWNER
//
// MessageText:
//
// Indicates a particular Security ID may not be assigned as the owner of an object.
//
int STATUS_INVALID_OWNER = 0xC000005A;
}

9 changes: 9 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/NtDll.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,13 @@ public int ZwQueryKey(HANDLE KeyHandle, int KeyInformationClass,
* NtQuerySecurityObject returns STATUS_SUCCESS or an appropriate error status.
*/
public int NtQuerySecurityObject(HANDLE handle, int SecurityInformation, Pointer SecurityDescriptor, int Length, IntByReference LengthNeeded);

/**
* Converts the specified NTSTATUS code to its equivalent system error code.
* @param Status [in]
* The NTSTATUS code to be converted.
* @return The function returns the corresponding system error code. ERROR_MR_MID_NOT_FOUND is returned when the specified NTSTATUS code
* does not have a corresponding system error code.
*/
public int RtlNtStatusToDosError(int Status);
}
160 changes: 134 additions & 26 deletions contrib/platform/src/com/sun/jna/platform/win32/WinNT.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import com.sun.jna.FromNativeContext;
import com.sun.jna.IntegerType;
Expand All @@ -50,6 +49,15 @@
@SuppressWarnings("serial")
public interface WinNT extends WinError, WinDef, WinBase, BaseTSD {

int MINCHAR = 0x80;
int MAXCHAR = 0x7f;
int MINSHORT = 0x8000;
int MAXSHORT = 0x7fff;
int MINLONG = 0x80000000;
int MAXLONG = 0x7fffffff;
int MAXBYTE = 0xff;
int MAXWORD = 0xffff;
int MAXDWORD = 0xffffffff;
//
// The following are masks for the predefined standard access types
//
Expand Down Expand Up @@ -2481,6 +2489,7 @@ protected List<String> getFieldOrder() {
int SE_RM_CONTROL_VALID = 0x00004000;
int SE_SELF_RELATIVE = 0x00008000;

int SECURITY_DESCRIPTOR_REVISION = 0x00000001;

public static class SECURITY_DESCRIPTOR extends Structure {
public static class ByReference extends SECURITY_DESCRIPTOR implements
Expand All @@ -2495,10 +2504,17 @@ public SECURITY_DESCRIPTOR() {
}

public SECURITY_DESCRIPTOR(byte[] data) {
super();
this.data = data;
useMemory(new Memory(data.length));
}

public SECURITY_DESCRIPTOR(int size) {
super();
useMemory(new Memory(size));
data = new byte[size];
}

public SECURITY_DESCRIPTOR(Pointer memory) {
super(memory);
read();
Expand All @@ -2510,9 +2526,27 @@ protected List<String> getFieldOrder() {
}
}

int ACL_REVISION = 2;
int ACL_REVISION_DS = 4;

// This is the history of ACL revisions. Add a new one whenever
// ACL_REVISION is updated
int ACL_REVISION1 = 1;
int ACL_REVISION2 = 2;
int ACL_REVISION3 = 3;
int ACL_REVISION4 = 4;
int MIN_ACL_REVISION = ACL_REVISION2;
int MAX_ACL_REVISION = ACL_REVISION4;

public static class ACL extends Structure {
public static final List<String> FIELDS = createFieldsOrder("AclRevision", "Sbz1", "AclSize", "AceCount", "Sbz2");

/*
* Maximum size chosen based on technet article:
* https://technet.microsoft.com/en-us/library/cc781716.aspx
*/
public static int MAX_ACL_SIZE = 64 * 1024;

public byte AclRevision;
public byte Sbz1;
public short AclSize;
Expand All @@ -2525,6 +2559,11 @@ public ACL() {
super();
}

public ACL(int size) {
super();
useMemory(new Memory(size));
}

public ACL(Pointer pointer) {
super(pointer);
read();
Expand Down Expand Up @@ -2560,6 +2599,31 @@ protected List<String> getFieldOrder() {
}
}

public static class PACLByReference extends ByReference {
public PACLByReference() {
this(null);
}

public PACLByReference(ACL h) {
super(Pointer.SIZE);
setValue(h);
}

public void setValue(ACL h) {
getPointer().setPointer(0, h != null ? h.getPointer() : null);
}

public ACL getValue() {
Pointer p = getPointer().getPointer(0);
if (p == null) {
return null;
}
else {
return new ACL(p);
}
}
}

public static class SECURITY_DESCRIPTOR_RELATIVE extends Structure {
public static class ByReference extends SECURITY_DESCRIPTOR_RELATIVE
implements Structure.ByReference {
Expand All @@ -2575,10 +2639,10 @@ public static class ByReference extends SECURITY_DESCRIPTOR_RELATIVE
public int Sacl;
public int Dacl;

private ACL DACL;
private PSID OWNER;
private PSID GROUP;
private ACL SACL;
private ACL DACL;

public SECURITY_DESCRIPTOR_RELATIVE() {
super();
Expand All @@ -2590,6 +2654,10 @@ public SECURITY_DESCRIPTOR_RELATIVE(byte[] data) {
setMembers();
}

public SECURITY_DESCRIPTOR_RELATIVE(int length) {
super(new Memory(length));
}

public SECURITY_DESCRIPTOR_RELATIVE(Pointer p) {
super(p);
setMembers();
Expand Down Expand Up @@ -2650,6 +2718,15 @@ public ACEStructure(Pointer p) {
super(p);
}

public ACEStructure(byte AceType, byte AceFlags, short AceSize, PSID psid) {
super();
this.AceType = AceType;
this.AceFlags = AceFlags;
this.AceSize = AceSize;
this.psid = psid;
write();
}

public String getSidString() {
return Advapi32Util.convertSidToStringSid(psid);
}
Expand Down Expand Up @@ -2680,46 +2757,69 @@ public ACE_HEADER(Pointer p) {
* ACCESS_ALLOWED_ACE and ACCESS_DENIED_ACE have the same structure layout
*/
public static abstract class ACCESS_ACEStructure extends ACEStructure {
public static final List<String> EXTRA_ABSTRACT_FIELDS = createFieldsOrder("Mask", "SidStart");
private static final AtomicReference<List<String>> fieldsHolder = new AtomicReference<List<String>>(null);
private static List<String> resolveEffectiveFields(List<String> baseFields) {
List<String> fields;
synchronized (fieldsHolder) {
fields = fieldsHolder.get();
if (fields == null) {
fields = createFieldsOrder(baseFields, EXTRA_ABSTRACT_FIELDS);
fieldsHolder.set(fields);
}
}

return fields;
}
public static final List<String> FIELDS = createFieldsOrder(ACEStructure.FIELDS, "Mask", "SidStart");

public int Mask;
/**
* first 4 bytes of the SID
* First 4 bytes of the SID
* Only used to have a valid field defined - use sid!
*/
public DWORD SidStart;
public byte[] SidStart = new byte[4];

public ACCESS_ACEStructure() {
super();
}

public ACCESS_ACEStructure(int Mask, byte AceType, byte AceFlags, PSID psid) {
super();
this.calculateSize(true);
this.AceType = AceType;
this.AceFlags = AceFlags;
this.AceSize = (short) (super.fieldOffset("SidStart") + psid.getBytes().length);
this.psid = psid;
this.Mask = Mask;
this.SidStart = psid.getPointer().getByteArray(0, SidStart.length);
this.allocateMemory(AceSize);
write();
}

public ACCESS_ACEStructure(Pointer p) {
super(p);
read();
// AceSize - size of public members of the structure + size of DWORD
// (SidStart)
int sizeOfSID = super.AceSize - size() + 4;
// ACE_HEADER + size of int (Mask)
int offsetOfSID = 4 + 4;
byte[] data = p.getByteArray(offsetOfSID, sizeOfSID);
psid = new PSID(data);
}

/**
* Write override due to psid not being a managed field
*/
@Override
public void write() {
super.write();
int offsetOfSID = super.fieldOffset("SidStart");
int sizeOfSID = super.AceSize - super.fieldOffset("SidStart");
if(psid != null) {
// Get bytes from the PSID
byte[] psidWrite = psid.getBytes();
assert psidWrite.length <= sizeOfSID;
// Write those bytes to native memory
getPointer().write(offsetOfSID, psidWrite, 0, sizeOfSID);
}
}

@Override
public void read() {
super.read();
int offsetOfSID = super.fieldOffset("SidStart");
int sizeOfSID = super.AceSize - super.fieldOffset("SidStart");
if(sizeOfSID > 0) {
psid = new PSID(getPointer().getByteArray(offsetOfSID, sizeOfSID));
} else {
psid = new PSID();
}
}

@Override
protected List<String> getFieldOrder() {
return resolveEffectiveFields(super.getFieldOrder());
return FIELDS;
}
}

Expand All @@ -2732,6 +2832,10 @@ public ACCESS_ALLOWED_ACE() {
public ACCESS_ALLOWED_ACE(Pointer p) {
super(p);
}

public ACCESS_ALLOWED_ACE(int Mask, byte AceFlags, PSID psid) {
super(Mask, ACCESS_ALLOWED_ACE_TYPE, AceFlags, psid);
}
}

/* Access denied ACE */
Expand All @@ -2743,6 +2847,10 @@ public ACCESS_DENIED_ACE() {
public ACCESS_DENIED_ACE(Pointer p) {
super(p);
}

public ACCESS_DENIED_ACE(int Mask, byte AceFlags, PSID psid) {
super(Mask, ACCESS_DENIED_ACE_TYPE, AceFlags, psid);
}
}

/* ACE types */
Expand Down
Loading