actor_windows.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package ipnauth
  4. import (
  5. "context"
  6. "errors"
  7. "golang.org/x/sys/windows"
  8. "tailscale.com/ipn"
  9. "tailscale.com/types/lazy"
  10. )
  11. // WindowsActor implements [Actor].
  12. var _ Actor = (*WindowsActor)(nil)
  13. // WindowsActor represents a logged in Windows user.
  14. type WindowsActor struct {
  15. ctx context.Context
  16. cancelCtx context.CancelFunc
  17. token WindowsToken
  18. uid ipn.WindowsUserID
  19. username lazy.SyncValue[string]
  20. }
  21. // NewWindowsActorWithToken returns a new [WindowsActor] for the user
  22. // represented by the given [windows.Token].
  23. // It takes ownership of the token.
  24. func NewWindowsActorWithToken(t windows.Token) (_ *WindowsActor, err error) {
  25. tok := newToken(t)
  26. uid, err := tok.UID()
  27. if err != nil {
  28. t.Close()
  29. return nil, err
  30. }
  31. ctx, cancelCtx := context.WithCancel(context.Background())
  32. return &WindowsActor{ctx: ctx, cancelCtx: cancelCtx, token: tok, uid: uid}, nil
  33. }
  34. // UserID implements [Actor].
  35. func (a *WindowsActor) UserID() ipn.WindowsUserID {
  36. return a.uid
  37. }
  38. // Username implements [Actor].
  39. func (a *WindowsActor) Username() (string, error) {
  40. return a.username.GetErr(a.token.Username)
  41. }
  42. // ClientID implements [Actor].
  43. func (a *WindowsActor) ClientID() (_ ClientID, ok bool) {
  44. // TODO(nickkhyl): assign and return a client ID when the actor
  45. // represents a connected LocalAPI client.
  46. return NoClientID, false
  47. }
  48. // Context implements [Actor].
  49. func (a *WindowsActor) Context() context.Context {
  50. return a.ctx
  51. }
  52. // CheckProfileAccess implements [Actor].
  53. func (a *WindowsActor) CheckProfileAccess(profile ipn.LoginProfileView, _ ProfileAccess, _ AuditLogFunc) error {
  54. if profile.LocalUserID() != a.UserID() {
  55. // TODO(nickkhyl): return errors of more specific types and have them
  56. // translated to the appropriate HTTP status codes in the API handler.
  57. return errors.New("the target profile does not belong to the user")
  58. }
  59. return nil
  60. }
  61. // IsLocalSystem implements [Actor].
  62. //
  63. // Deprecated: this method exists for compatibility with the current (as of 2025-02-06)
  64. // permission model and will be removed as we progress on tailscale/corp#18342.
  65. func (a *WindowsActor) IsLocalSystem() bool {
  66. // https://web.archive.org/web/2024/https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers
  67. const systemUID = ipn.WindowsUserID("S-1-5-18")
  68. return a.uid == systemUID
  69. }
  70. // IsLocalAdmin implements [Actor].
  71. //
  72. // Deprecated: this method exists for compatibility with the current (as of 2025-02-06)
  73. // permission model and will be removed as we progress on tailscale/corp#18342.
  74. func (a *WindowsActor) IsLocalAdmin(operatorUID string) bool {
  75. return a.token.IsElevated()
  76. }
  77. // Close releases resources associated with the actor
  78. // and cancels its context.
  79. func (a *WindowsActor) Close() error {
  80. if a.token != nil {
  81. if err := a.token.Close(); err != nil {
  82. return err
  83. }
  84. a.token = nil
  85. }
  86. a.cancelCtx()
  87. return nil
  88. }