| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- // Copyright (c) 2022 Tailscale Inc & AUTHORS. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- //go:build windows
- package wingoes
- import (
- "unsafe"
- "golang.org/x/sys/windows"
- )
- // UserSIDs contains pointers to the SIDs for a user and their primary group.
- type UserSIDs struct {
- User *windows.SID
- PrimaryGroup *windows.SID
- }
- // CurrentProcessUserSIDs returns a UserSIDs containing the SIDs of the user
- // and primary group who own the current process.
- func CurrentProcessUserSIDs() (*UserSIDs, error) {
- token, err := windows.OpenCurrentProcessToken()
- if err != nil {
- return nil, err
- }
- defer token.Close()
- userInfo, err := getTokenInfo[windows.Tokenuser](token, windows.TokenUser)
- if err != nil {
- return nil, err
- }
- primaryGroup, err := getTokenInfo[windows.Tokenprimarygroup](token, windows.TokenPrimaryGroup)
- if err != nil {
- return nil, err
- }
- // We just want the SIDs, not the rest of the structs that were output.
- userSid, err := userInfo.User.Sid.Copy()
- if err != nil {
- return nil, err
- }
- primaryGroupSid, err := primaryGroup.PrimaryGroup.Copy()
- if err != nil {
- return nil, err
- }
- return &UserSIDs{User: userSid, PrimaryGroup: primaryGroupSid}, nil
- }
- func getTokenInfo[T any](token windows.Token, infoClass uint32) (*T, error) {
- var buf []byte
- var desiredLen uint32
- err := windows.GetTokenInformation(token, infoClass, nil, 0, &desiredLen)
- for err != nil {
- if err != windows.ERROR_INSUFFICIENT_BUFFER {
- return nil, err
- }
- buf = make([]byte, desiredLen)
- err = windows.GetTokenInformation(token, infoClass, &buf[0], desiredLen, &desiredLen)
- }
- return (*T)(unsafe.Pointer(&buf[0])), nil
- }
|