--- /dev/null
+On Windows, [Current], [Lookup] and [LookupId] now supports the
+following built-in service user accounts:
+- `NT AUTHORITY\SYSTEM`
+- `NT AUTHORITY\LOCAL SERVICE`
+- `NT AUTHORITY\NETWORK SERVICE`
 
        }
        return (*TOKEN_GROUPS)(i), nil
 }
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-sid_identifier_authority
+type SID_IDENTIFIER_AUTHORITY struct {
+       Value [6]byte
+}
+
+const (
+       SID_REVISION = 1
+       // https://learn.microsoft.com/en-us/windows/win32/services/localsystem-account
+       SECURITY_LOCAL_SYSTEM_RID = 18
+       // https://learn.microsoft.com/en-us/windows/win32/services/localservice-account
+       SECURITY_LOCAL_SERVICE_RID = 19
+       // https://learn.microsoft.com/en-us/windows/win32/services/networkservice-account
+       SECURITY_NETWORK_SERVICE_RID = 20
+)
+
+var SECURITY_NT_AUTHORITY = SID_IDENTIFIER_AUTHORITY{
+       Value: [6]byte{0, 0, 0, 0, 0, 5},
+}
+
+//sys  IsValidSid(sid *syscall.SID) (valid bool) = advapi32.IsValidSid
+//sys  GetSidIdentifierAuthority(sid *syscall.SID) (idauth *SID_IDENTIFIER_AUTHORITY) = advapi32.GetSidIdentifierAuthority
+//sys  GetSidSubAuthority(sid *syscall.SID, subAuthorityIdx uint32) (subAuth *uint32) = advapi32.GetSidSubAuthority
+//sys  GetSidSubAuthorityCount(sid *syscall.SID) (count *uint8) = advapi32.GetSidSubAuthorityCount
 
 
        procAdjustTokenPrivileges             = modadvapi32.NewProc("AdjustTokenPrivileges")
        procDuplicateTokenEx                  = modadvapi32.NewProc("DuplicateTokenEx")
+       procGetSidIdentifierAuthority         = modadvapi32.NewProc("GetSidIdentifierAuthority")
+       procGetSidSubAuthority                = modadvapi32.NewProc("GetSidSubAuthority")
+       procGetSidSubAuthorityCount           = modadvapi32.NewProc("GetSidSubAuthorityCount")
        procImpersonateLoggedOnUser           = modadvapi32.NewProc("ImpersonateLoggedOnUser")
        procImpersonateSelf                   = modadvapi32.NewProc("ImpersonateSelf")
+       procIsValidSid                        = modadvapi32.NewProc("IsValidSid")
        procLogonUserW                        = modadvapi32.NewProc("LogonUserW")
        procLookupPrivilegeValueW             = modadvapi32.NewProc("LookupPrivilegeValueW")
        procOpenSCManagerW                    = modadvapi32.NewProc("OpenSCManagerW")
        return
 }
 
+func GetSidIdentifierAuthority(sid *syscall.SID) (idauth *SID_IDENTIFIER_AUTHORITY) {
+       r0, _, _ := syscall.Syscall(procGetSidIdentifierAuthority.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
+       idauth = (*SID_IDENTIFIER_AUTHORITY)(unsafe.Pointer(r0))
+       return
+}
+
+func GetSidSubAuthority(sid *syscall.SID, subAuthorityIdx uint32) (subAuth *uint32) {
+       r0, _, _ := syscall.Syscall(procGetSidSubAuthority.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(subAuthorityIdx), 0)
+       subAuth = (*uint32)(unsafe.Pointer(r0))
+       return
+}
+
+func GetSidSubAuthorityCount(sid *syscall.SID) (count *uint8) {
+       r0, _, _ := syscall.Syscall(procGetSidSubAuthorityCount.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
+       count = (*uint8)(unsafe.Pointer(r0))
+       return
+}
+
 func ImpersonateLoggedOnUser(token syscall.Token) (err error) {
        r1, _, e1 := syscall.Syscall(procImpersonateLoggedOnUser.Addr(), 1, uintptr(token), 0, 0)
        if r1 == 0 {
        return
 }
 
+func IsValidSid(sid *syscall.SID) (valid bool) {
+       r0, _, _ := syscall.Syscall(procIsValidSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
+       valid = r0 != 0
+       return
+}
+
 func LogonUser(username *uint16, domain *uint16, password *uint16, logonType uint32, logonProvider uint32, token *syscall.Token) (err error) {
        r1, _, e1 := syscall.Syscall6(procLogonUserW.Addr(), 6, uintptr(unsafe.Pointer(username)), uintptr(unsafe.Pointer(domain)), uintptr(unsafe.Pointer(password)), uintptr(logonType), uintptr(logonProvider), uintptr(unsafe.Pointer(token)))
        if r1 == 0 {
 
        }
 }
 
+func isServiceAccount(sid *syscall.SID) bool {
+       if !windows.IsValidSid(sid) {
+               // We don't accept SIDs from the public API, so this should never happen.
+               // Better be on the safe side and validate anyway.
+               return false
+       }
+       // The following RIDs are considered service user accounts as per
+       // https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids and
+       // https://learn.microsoft.com/en-us/windows/win32/services/service-user-accounts:
+       // - "S-1-5-18": LocalSystem
+       // - "S-1-5-19": LocalService
+       // - "S-1-5-20": NetworkService
+       if *windows.GetSidSubAuthorityCount(sid) != windows.SID_REVISION ||
+               *windows.GetSidIdentifierAuthority(sid) != windows.SECURITY_NT_AUTHORITY {
+               return false
+       }
+       switch *windows.GetSidSubAuthority(sid, 0) {
+       case windows.SECURITY_LOCAL_SYSTEM_RID,
+               windows.SECURITY_LOCAL_SERVICE_RID,
+               windows.SECURITY_NETWORK_SERVICE_RID:
+               return true
+       }
+       return false
+}
+
+func isValidUserAccountType(sid *syscall.SID, sidType uint32) bool {
+       switch sidType {
+       case syscall.SidTypeUser:
+               return true
+       case syscall.SidTypeWellKnownGroup:
+               return isServiceAccount(sid)
+       }
+       return false
+}
+
+func isValidGroupAccountType(sidType uint32) bool {
+       switch sidType {
+       case syscall.SidTypeGroup:
+               return true
+       case syscall.SidTypeWellKnownGroup:
+               // Some well-known groups are also considered service accounts,
+               // so isValidUserAccountType would return true for them.
+               // We have historically allowed them in LookupGroup and LookupGroupId,
+               // so don't treat them as invalid here.
+               return true
+       case syscall.SidTypeAlias:
+               // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/7b2aeb27-92fc-41f6-8437-deb65d950921#gt_0387e636-5654-4910-9519-1f8326cf5ec0
+               // SidTypeAlias should also be treated as a group type next to SidTypeGroup
+               // and SidTypeWellKnownGroup:
+               // "alias object -> resource group: A group object..."
+               //
+               // Tests show that "Administrators" can be considered of type SidTypeAlias.
+               return true
+       }
+       return false
+}
+
 // lookupUsernameAndDomain obtains the username and domain for usid.
-func lookupUsernameAndDomain(usid *syscall.SID) (username, domain string, e error) {
-       username, domain, t, e := usid.LookupAccount("")
+func lookupUsernameAndDomain(usid *syscall.SID) (username, domain string, sidType uint32, e error) {
+       username, domain, sidType, e = usid.LookupAccount("")
        if e != nil {
-               return "", "", e
+               return "", "", 0, e
        }
-       if t != syscall.SidTypeUser {
-               return "", "", fmt.Errorf("user: should be user account type, not %d", t)
+       if !isValidUserAccountType(usid, sidType) {
+               return "", "", 0, fmt.Errorf("user: should be user account type, not %d", sidType)
        }
-       return username, domain, nil
+       return username, domain, sidType, nil
 }
 
 // findHomeDirInRegistry finds the user home path based on the uid.
        if e != nil {
                return "", e
        }
-       // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/7b2aeb27-92fc-41f6-8437-deb65d950921#gt_0387e636-5654-4910-9519-1f8326cf5ec0
-       // SidTypeAlias should also be treated as a group type next to SidTypeGroup
-       // and SidTypeWellKnownGroup:
-       // "alias object -> resource group: A group object..."
-       //
-       // Tests show that "Administrators" can be considered of type SidTypeAlias.
-       if t != syscall.SidTypeGroup && t != syscall.SidTypeWellKnownGroup && t != syscall.SidTypeAlias {
+       if !isValidGroupAccountType(t) {
                return "", fmt.Errorf("lookupGroupName: should be group account type, not %d", t)
        }
        return sid.String()
 }
 
 func newUserFromSid(usid *syscall.SID) (*User, error) {
-       username, domain, e := lookupUsernameAndDomain(usid)
-       if e != nil {
-               return nil, e
-       }
-       gid, e := lookupUserPrimaryGroup(username, domain)
+       username, domain, sidType, e := lookupUsernameAndDomain(usid)
        if e != nil {
                return nil, e
        }
        if e != nil {
                return nil, e
        }
+       var gid string
+       if sidType == syscall.SidTypeWellKnownGroup {
+               // The SID does not contain a domain; this function's domain variable has
+               // been populated with the SID's identifier authority. This happens with
+               // special service user accounts such as "NT AUTHORITY\LocalSystem".
+               // In this case, gid is the same as the user SID.
+               gid = uid
+       } else {
+               gid, e = lookupUserPrimaryGroup(username, domain)
+               if e != nil {
+                       return nil, e
+               }
+       }
        // If this user has logged in at least once their home path should be stored
        // in the registry under the specified SID. References:
        // https://social.technet.microsoft.com/wiki/contents/articles/13895.how-to-remove-a-corrupted-user-profile-from-the-registry.aspx
        if e != nil {
                return nil, e
        }
-       if t != syscall.SidTypeUser {
+       if !isValidUserAccountType(sid, t) {
                return nil, fmt.Errorf("user: should be user account type, not %d", t)
        }
        return newUserFromSid(sid)
        if err != nil {
                return nil, err
        }
-       if t != syscall.SidTypeGroup && t != syscall.SidTypeWellKnownGroup && t != syscall.SidTypeAlias {
+       if !isValidGroupAccountType(t) {
                return nil, fmt.Errorf("lookupGroupId: should be group account type, not %d", t)
        }
        return &Group{Name: groupname, Gid: gid}, nil
                if err != nil {
                        return nil, err
                }
-               username, domain, err := lookupUsernameAndDomain(sid)
+               username, domain, _, err := lookupUsernameAndDomain(sid)
                if err != nil {
                        return nil, err
                }
 
                t.Errorf("%+v.GroupIds() = %v; does not contain user GID %s", user, gids, user.Gid)
        }
 }
+
+var serviceAccounts = []struct {
+       sid  string
+       name string
+}{
+       {"S-1-5-18", "NT AUTHORITY\\SYSTEM"},
+       {"S-1-5-19", "NT AUTHORITY\\LOCAL SERVICE"},
+       {"S-1-5-20", "NT AUTHORITY\\NETWORK SERVICE"},
+}
+
+func TestLookupServiceAccount(t *testing.T) {
+       t.Parallel()
+       for _, tt := range serviceAccounts {
+               u, err := Lookup(tt.name)
+               if err != nil {
+                       t.Errorf("Lookup(%q): %v", tt.name, err)
+                       continue
+               }
+               if u.Uid != tt.sid {
+                       t.Errorf("unexpected uid for %q; got %q, want %q", u.Name, u.Uid, tt.sid)
+               }
+       }
+}
+
+func TestLookupIdServiceAccount(t *testing.T) {
+       t.Parallel()
+       for _, tt := range serviceAccounts {
+               u, err := LookupId(tt.sid)
+               if err != nil {
+                       t.Errorf("LookupId(%q): %v", tt.sid, err)
+                       continue
+               }
+               if u.Gid != tt.sid {
+                       t.Errorf("unexpected gid for %q; got %q, want %q", u.Name, u.Gid, tt.sid)
+               }
+               if u.Username != tt.name {
+                       t.Errorf("unexpected user name for %q; got %q, want %q", u.Gid, u.Username, tt.name)
+               }
+       }
+}
+
+func TestLookupGroupServiceAccount(t *testing.T) {
+       t.Parallel()
+       for _, tt := range serviceAccounts {
+               u, err := LookupGroup(tt.name)
+               if err != nil {
+                       t.Errorf("LookupGroup(%q): %v", tt.name, err)
+                       continue
+               }
+               if u.Gid != tt.sid {
+                       t.Errorf("unexpected gid for %q; got %q, want %q", u.Name, u.Gid, tt.sid)
+               }
+       }
+}
+
+func TestLookupGroupIdServiceAccount(t *testing.T) {
+       t.Parallel()
+       for _, tt := range serviceAccounts {
+               u, err := LookupGroupId(tt.sid)
+               if err != nil {
+                       t.Errorf("LookupGroupId(%q): %v", tt.sid, err)
+                       continue
+               }
+               if u.Gid != tt.sid {
+                       t.Errorf("unexpected gid for %q; got %q, want %q", u.Name, u.Gid, tt.sid)
+               }
+       }
+}