Skip to content

Commit

Permalink
Merge pull request #738 from Seven10Storage/mod-security
Browse files Browse the repository at this point in the history
Adding security functions and RtlNtStatusToDosError to NtDll
  • Loading branch information
matthiasblaesing authored Dec 12, 2016
2 parents c8ecadb + 922dad1 commit 82c8638
Show file tree
Hide file tree
Showing 8 changed files with 842 additions and 26 deletions.
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

0 comments on commit 82c8638

Please sign in to comment.