Skip to content

Commit c33d3f0

Browse files
Merge pull request #1191 from dbwiddis/primarygroup
Add getTokenPrimaryGroup to Advapi32Util
2 parents 5ee1575 + 1c58a68 commit c33d3f0

File tree

4 files changed

+82
-4
lines changed

4 files changed

+82
-4
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Features
1212
* [#1168](https://github.com/java-native-access/jna/pull/1168): Add `c.s.j.p.win32.Kernel32#SetProcessAffinityMask` - [@dbwiddis](https://github.com/dbwiddis).
1313
* [#1169](https://github.com/java-native-access/jna/issues/1169): Wait for process in getLinuxLdPaths - [@rdesgroppes](https://github.com/rdesgroppes).
1414
* [#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).
15+
* [#1191](https://github.com/java-native-access/jna/pull/1191): Add `c.s.j.p.win32.Advapi32Util#getTokenPrimaryGroup` - [@dbwiddis](https://github.com/dbwiddis).
1516

1617
Bug Fixes
1718
---------

contrib/platform/src/com/sun/jna/platform/win32/Advapi32Util.java

+41
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import com.sun.jna.Memory;
6464
import com.sun.jna.Native;
6565
import com.sun.jna.Pointer;
66+
import com.sun.jna.platform.win32.Advapi32Util.Account;
6667
import com.sun.jna.platform.win32.WinBase.FE_EXPORT_FUNC;
6768
import com.sun.jna.platform.win32.WinBase.FE_IMPORT_FUNC;
6869
import com.sun.jna.platform.win32.WinBase.FILETIME;
@@ -86,6 +87,7 @@
8687
import com.sun.jna.platform.win32.WinNT.SECURITY_IMPERSONATION_LEVEL;
8788
import com.sun.jna.platform.win32.WinNT.SID_AND_ATTRIBUTES;
8889
import com.sun.jna.platform.win32.WinNT.SID_NAME_USE;
90+
import com.sun.jna.platform.win32.WinNT.TOKEN_PRIMARY_GROUP;
8991
import com.sun.jna.platform.win32.WinNT.TOKEN_TYPE;
9092
import com.sun.jna.platform.win32.WinReg.HKEY;
9193
import com.sun.jna.platform.win32.WinReg.HKEYByReference;
@@ -475,6 +477,45 @@ public static Account[] getTokenGroups(HANDLE hToken) {
475477
return userGroups.toArray(new Account[0]);
476478
}
477479

480+
/**
481+
* This function returns the primary group associated with a security token,
482+
* such as a user token.
483+
*
484+
* @param hToken
485+
* Token.
486+
* @return Token primary group.
487+
*/
488+
public static Account getTokenPrimaryGroup(HANDLE hToken) {
489+
// get token group information size
490+
IntByReference tokenInformationLength = new IntByReference();
491+
if (Advapi32.INSTANCE.GetTokenInformation(hToken, WinNT.TOKEN_INFORMATION_CLASS.TokenPrimaryGroup, null, 0,
492+
tokenInformationLength)) {
493+
throw new RuntimeException("Expected GetTokenInformation to fail with ERROR_INSUFFICIENT_BUFFER");
494+
}
495+
int rc = Kernel32.INSTANCE.GetLastError();
496+
if (rc != W32Errors.ERROR_INSUFFICIENT_BUFFER) {
497+
throw new Win32Exception(rc);
498+
}
499+
// get token group information
500+
WinNT.TOKEN_PRIMARY_GROUP primaryGroup = new WinNT.TOKEN_PRIMARY_GROUP(tokenInformationLength.getValue());
501+
if (!Advapi32.INSTANCE.GetTokenInformation(hToken, WinNT.TOKEN_INFORMATION_CLASS.TokenPrimaryGroup,
502+
primaryGroup, tokenInformationLength.getValue(), tokenInformationLength)) {
503+
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
504+
}
505+
Account group;
506+
try {
507+
group = Advapi32Util.getAccountBySid(primaryGroup.PrimaryGroup);
508+
} catch (Exception e) {
509+
group = new Account();
510+
group.sid = primaryGroup.PrimaryGroup.getBytes();
511+
group.sidString = Advapi32Util.convertSidToStringSid(primaryGroup.PrimaryGroup);
512+
group.name = group.sidString;
513+
group.fqn = group.sidString;
514+
group.accountType = SID_NAME_USE.SidTypeGroup;
515+
}
516+
return group;
517+
}
518+
478519
/**
479520
* This function returns the information about the user who owns a security
480521
* token,

contrib/platform/src/com/sun/jna/platform/win32/WinNT.java

+28
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.sun.jna.PointerType;
3333
import com.sun.jna.Structure;
3434
import com.sun.jna.Structure.FieldOrder;
35+
import com.sun.jna.platform.win32.WinNT.PSID;
3536
import com.sun.jna.Union;
3637
import com.sun.jna.ptr.ByReference;
3738
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
@@ -427,6 +428,33 @@ public TOKEN_USER(int size) {
427428
}
428429
}
429430

431+
/**
432+
* The TOKEN_PRIMARY_GROUP structure specifies a group security identifier (SID)
433+
* for an access token.
434+
*/
435+
@FieldOrder({ "PrimaryGroup" })
436+
public static class TOKEN_PRIMARY_GROUP extends Structure {
437+
/**
438+
* A pointer to a SID structure representing a group that will become the
439+
* primary group of any objects created by a process using this access token.
440+
* The SID must be one of the group SIDs already in the token.
441+
*/
442+
public PSID.ByReference PrimaryGroup;
443+
444+
public TOKEN_PRIMARY_GROUP() {
445+
super();
446+
}
447+
448+
public TOKEN_PRIMARY_GROUP(Pointer memory) {
449+
super(memory);
450+
read();
451+
}
452+
453+
public TOKEN_PRIMARY_GROUP(int size) {
454+
super(new Memory(size));
455+
}
456+
}
457+
430458
/**
431459
* The TOKEN_GROUPS structure contains information about the group security
432460
* identifiers (SIDs) in an access token.

contrib/platform/test/com/sun/jna/platform/win32/Advapi32UtilTest.java

+12-4
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,24 @@ public void testGetUserGroups() {
171171
try {
172172
HANDLEByReference phUser = new HANDLEByReference();
173173
try {
174-
assertTrue(Advapi32.INSTANCE.LogonUser(userInfo.usri1_name,
175-
null, userInfo.usri1_password, WinBase.LOGON32_LOGON_NETWORK,
176-
WinBase.LOGON32_PROVIDER_DEFAULT, phUser));
174+
assertTrue(Advapi32.INSTANCE.LogonUser(userInfo.usri1_name, null, userInfo.usri1_password,
175+
WinBase.LOGON32_LOGON_NETWORK, WinBase.LOGON32_PROVIDER_DEFAULT, phUser));
176+
Account primaryGroup = Advapi32Util.getTokenPrimaryGroup(phUser.getValue());
177+
assertTrue(primaryGroup.name.length() > 0);
178+
assertTrue(primaryGroup.sidString.length() > 0);
179+
assertTrue(primaryGroup.sid.length > 0);
177180
Account[] groups = Advapi32Util.getTokenGroups(phUser.getValue());
181+
boolean primaryGroupFound = false;
178182
assertTrue(groups.length > 0);
179-
for(Account group : groups) {
183+
for (Account group : groups) {
180184
assertTrue(group.name.length() > 0);
181185
assertTrue(group.sidString.length() > 0);
182186
assertTrue(group.sid.length > 0);
187+
if (primaryGroup.name.equals(group.name)) {
188+
primaryGroupFound = true;
189+
}
183190
}
191+
assertTrue("PrimaryGroup must be in group list", primaryGroupFound);
184192
} finally {
185193
HANDLE hUser = phUser.getValue();
186194
if (!WinBase.INVALID_HANDLE_VALUE.equals(hUser)) {

0 commit comments

Comments
 (0)