util.go 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright (c) 2022 Tailscale Inc & AUTHORS. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build windows
  5. package wingoes
  6. import (
  7. "unsafe"
  8. "golang.org/x/sys/windows"
  9. )
  10. // UserSIDs contains pointers to the SIDs for a user and their primary group.
  11. type UserSIDs struct {
  12. User *windows.SID
  13. PrimaryGroup *windows.SID
  14. }
  15. // CurrentProcessUserSIDs returns a UserSIDs containing the SIDs of the user
  16. // and primary group who own the current process.
  17. func CurrentProcessUserSIDs() (*UserSIDs, error) {
  18. token, err := windows.OpenCurrentProcessToken()
  19. if err != nil {
  20. return nil, err
  21. }
  22. defer token.Close()
  23. userInfo, err := getTokenInfo[windows.Tokenuser](token, windows.TokenUser)
  24. if err != nil {
  25. return nil, err
  26. }
  27. primaryGroup, err := getTokenInfo[windows.Tokenprimarygroup](token, windows.TokenPrimaryGroup)
  28. if err != nil {
  29. return nil, err
  30. }
  31. // We just want the SIDs, not the rest of the structs that were output.
  32. userSid, err := userInfo.User.Sid.Copy()
  33. if err != nil {
  34. return nil, err
  35. }
  36. primaryGroupSid, err := primaryGroup.PrimaryGroup.Copy()
  37. if err != nil {
  38. return nil, err
  39. }
  40. return &UserSIDs{User: userSid, PrimaryGroup: primaryGroupSid}, nil
  41. }
  42. func getTokenInfo[T any](token windows.Token, infoClass uint32) (*T, error) {
  43. var buf []byte
  44. var desiredLen uint32
  45. err := windows.GetTokenInformation(token, infoClass, nil, 0, &desiredLen)
  46. for err != nil {
  47. if err != windows.ERROR_INSUFFICIENT_BUFFER {
  48. return nil, err
  49. }
  50. buf = make([]byte, desiredLen)
  51. err = windows.GetTokenInformation(token, infoClass, &buf[0], desiredLen, &desiredLen)
  52. }
  53. return (*T)(unsafe.Pointer(&buf[0])), nil
  54. }