Skip to content

Commit

Permalink
Merge pull request #1191 from dbwiddis/primarygroup
Browse files Browse the repository at this point in the history
Add getTokenPrimaryGroup to Advapi32Util
  • Loading branch information
matthiasblaesing authored May 15, 2020
2 parents 5ee1575 + 1c58a68 commit c33d3f0
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Features
* [#1168](https://github.com/java-native-access/jna/pull/1168): Add `c.s.j.p.win32.Kernel32#SetProcessAffinityMask` - [@dbwiddis](https://github.com/dbwiddis).
* [#1169](https://github.com/java-native-access/jna/issues/1169): Wait for process in getLinuxLdPaths - [@rdesgroppes](https://github.com/rdesgroppes).
* [#1178](https://github.com/java-native-access/jna/pull/1178): Add `c.s.j.p.win32.IPHlpAPI#GetTcpStatistics`, `c.s.j.p.win32.IPHlpAPI#GetUdpStatistics`, `c.s.j.p.win32.IPHlpAPI#GetTcpStatisticsEx` and `c.s.j.p.win32.IPHlpAPI#GetUdpStatisticsEx` - [@dbwiddis](https://github.com/dbwiddis).
* [#1191](https://github.com/java-native-access/jna/pull/1191): Add `c.s.j.p.win32.Advapi32Util#getTokenPrimaryGroup` - [@dbwiddis](https://github.com/dbwiddis).

Bug Fixes
---------
Expand Down
41 changes: 41 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 @@ -63,6 +63,7 @@
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Advapi32Util.Account;
import com.sun.jna.platform.win32.WinBase.FE_EXPORT_FUNC;
import com.sun.jna.platform.win32.WinBase.FE_IMPORT_FUNC;
import com.sun.jna.platform.win32.WinBase.FILETIME;
Expand All @@ -86,6 +87,7 @@
import com.sun.jna.platform.win32.WinNT.SECURITY_IMPERSONATION_LEVEL;
import com.sun.jna.platform.win32.WinNT.SID_AND_ATTRIBUTES;
import com.sun.jna.platform.win32.WinNT.SID_NAME_USE;
import com.sun.jna.platform.win32.WinNT.TOKEN_PRIMARY_GROUP;
import com.sun.jna.platform.win32.WinNT.TOKEN_TYPE;
import com.sun.jna.platform.win32.WinReg.HKEY;
import com.sun.jna.platform.win32.WinReg.HKEYByReference;
Expand Down Expand Up @@ -475,6 +477,45 @@ public static Account[] getTokenGroups(HANDLE hToken) {
return userGroups.toArray(new Account[0]);
}

/**
* This function returns the primary group associated with a security token,
* such as a user token.
*
* @param hToken
* Token.
* @return Token primary group.
*/
public static Account getTokenPrimaryGroup(HANDLE hToken) {
// get token group information size
IntByReference tokenInformationLength = new IntByReference();
if (Advapi32.INSTANCE.GetTokenInformation(hToken, WinNT.TOKEN_INFORMATION_CLASS.TokenPrimaryGroup, null, 0,
tokenInformationLength)) {
throw new RuntimeException("Expected GetTokenInformation to fail with ERROR_INSUFFICIENT_BUFFER");
}
int rc = Kernel32.INSTANCE.GetLastError();
if (rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
throw new Win32Exception(rc);
}
// get token group information
WinNT.TOKEN_PRIMARY_GROUP primaryGroup = new WinNT.TOKEN_PRIMARY_GROUP(tokenInformationLength.getValue());
if (!Advapi32.INSTANCE.GetTokenInformation(hToken, WinNT.TOKEN_INFORMATION_CLASS.TokenPrimaryGroup,
primaryGroup, tokenInformationLength.getValue(), tokenInformationLength)) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
Account group;
try {
group = Advapi32Util.getAccountBySid(primaryGroup.PrimaryGroup);
} catch (Exception e) {
group = new Account();
group.sid = primaryGroup.PrimaryGroup.getBytes();
group.sidString = Advapi32Util.convertSidToStringSid(primaryGroup.PrimaryGroup);
group.name = group.sidString;
group.fqn = group.sidString;
group.accountType = SID_NAME_USE.SidTypeGroup;
}
return group;
}

/**
* This function returns the information about the user who owns a security
* token,
Expand Down
28 changes: 28 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/WinNT.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.sun.jna.PointerType;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
import com.sun.jna.platform.win32.WinNT.PSID;
import com.sun.jna.Union;
import com.sun.jna.ptr.ByReference;
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
Expand Down Expand Up @@ -427,6 +428,33 @@ public TOKEN_USER(int size) {
}
}

/**
* The TOKEN_PRIMARY_GROUP structure specifies a group security identifier (SID)
* for an access token.
*/
@FieldOrder({ "PrimaryGroup" })
public static class TOKEN_PRIMARY_GROUP extends Structure {
/**
* A pointer to a SID structure representing a group that will become the
* primary group of any objects created by a process using this access token.
* The SID must be one of the group SIDs already in the token.
*/
public PSID.ByReference PrimaryGroup;

public TOKEN_PRIMARY_GROUP() {
super();
}

public TOKEN_PRIMARY_GROUP(Pointer memory) {
super(memory);
read();
}

public TOKEN_PRIMARY_GROUP(int size) {
super(new Memory(size));
}
}

/**
* The TOKEN_GROUPS structure contains information about the group security
* identifiers (SIDs) in an access token.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,16 +171,24 @@ public void testGetUserGroups() {
try {
HANDLEByReference phUser = new HANDLEByReference();
try {
assertTrue(Advapi32.INSTANCE.LogonUser(userInfo.usri1_name,
null, userInfo.usri1_password, WinBase.LOGON32_LOGON_NETWORK,
WinBase.LOGON32_PROVIDER_DEFAULT, phUser));
assertTrue(Advapi32.INSTANCE.LogonUser(userInfo.usri1_name, null, userInfo.usri1_password,
WinBase.LOGON32_LOGON_NETWORK, WinBase.LOGON32_PROVIDER_DEFAULT, phUser));
Account primaryGroup = Advapi32Util.getTokenPrimaryGroup(phUser.getValue());
assertTrue(primaryGroup.name.length() > 0);
assertTrue(primaryGroup.sidString.length() > 0);
assertTrue(primaryGroup.sid.length > 0);
Account[] groups = Advapi32Util.getTokenGroups(phUser.getValue());
boolean primaryGroupFound = false;
assertTrue(groups.length > 0);
for(Account group : groups) {
for (Account group : groups) {
assertTrue(group.name.length() > 0);
assertTrue(group.sidString.length() > 0);
assertTrue(group.sid.length > 0);
if (primaryGroup.name.equals(group.name)) {
primaryGroupFound = true;
}
}
assertTrue("PrimaryGroup must be in group list", primaryGroupFound);
} finally {
HANDLE hUser = phUser.getValue();
if (!WinBase.INVALID_HANDLE_VALUE.equals(hUser)) {
Expand Down

0 comments on commit c33d3f0

Please sign in to comment.