windows: add token group adjustment function

We have the useful AdjustTokenPrivileges, but we don't have the equally
as useful AdjustTokenGroups function. So this CL adds it.

Change-Id: Ic09b4688ee5ec7f1a626a21216a85b075961aad5
Reviewed-on: https://go-review.googlesource.com/c/sys/+/176859
Run-TryBot: Jason Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
diff --git a/windows/security_windows.go b/windows/security_windows.go
index 68e33ca..f27fd7c 100644
--- a/windows/security_windows.go
+++ b/windows/security_windows.go
@@ -591,6 +591,7 @@
 //sys	SetThreadToken(thread *Handle, token Token) (err error) = advapi32.SetThreadToken
 //sys	LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW
 //sys	AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges
+//sys	AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) = advapi32.AdjustTokenGroups
 //sys	GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
 //sys	SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) = advapi32.SetTokenInformation
 //sys	DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) = advapi32.DuplicateTokenEx
diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go
index 3bc5c3d..624d02f 100644
--- a/windows/zsyscall_windows.go
+++ b/windows/zsyscall_windows.go
@@ -267,6 +267,7 @@
 	procSetThreadToken                     = modadvapi32.NewProc("SetThreadToken")
 	procLookupPrivilegeValueW              = modadvapi32.NewProc("LookupPrivilegeValueW")
 	procAdjustTokenPrivileges              = modadvapi32.NewProc("AdjustTokenPrivileges")
+	procAdjustTokenGroups                  = modadvapi32.NewProc("AdjustTokenGroups")
 	procGetTokenInformation                = modadvapi32.NewProc("GetTokenInformation")
 	procSetTokenInformation                = modadvapi32.NewProc("SetTokenInformation")
 	procDuplicateTokenEx                   = modadvapi32.NewProc("DuplicateTokenEx")
@@ -2919,6 +2920,24 @@
 	return
 }
 
+func AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) {
+	var _p0 uint32
+	if resetToDefault {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := syscall.Syscall6(procAdjustTokenGroups.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
 func GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) {
 	r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(token), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0)
 	if r1 == 0 {