windows: add SID getter functions for the various components

These allow actual inspection of SIDs. For example, it might be
desirable to iterate through the group SIDs in order to find one set by
SERVICE_CONFIG_SERVICE_SID_INFO:

    for _, g := range groups {
        if g.Attributes != windows.SE_GROUP_ENABLED|windows.SE_GROUP_ENABLED_BY_DEFAULT|windows.SE_GROUP_OWNER {
            continue
        }
        if !g.Sid.IsValid() {
            continue
        }
        if g.Sid.IdentifierAuthority() != windows.SECURITY_NT_AUTHORITY {
            continue
        }
        if g.Sid.SubAuthorityCount() < 6 || g.Sid.SubAuthority(0) != 80 {
            continue
        }
        sid = g.Sid
        break
    }

Another usage of the APIs added would be to find if a user is in the
administrator group with either an elevated or unelevated token:

    isAdmin := false
    for _, g := range groups {
        if g.Attributes&(windows.SE_GROUP_ENABLED|windows.SE_GROUP_USE_FOR_DENY_ONLY) == 0 {
            continue
	}
        if !g.Sid.IsWellKnown(windows.WinBuiltinAdministratorsSid) {
            continue
	}
        isAdmin = true
        break
    }

Change-Id: I8f8dc8d37b71ec58fd51e21ea1f1b3aada6d66b0
Reviewed-on: https://go-review.googlesource.com/c/sys/+/177841
Run-TryBot: Jason Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
Jason A. Donenfeld
2019-05-26 03:56:09 +00:00
committed by Alex Brainman
parent e44a3b55db
commit 2219a0101f
2 changed files with 86 additions and 12 deletions
+35
View File
@@ -259,8 +259,13 @@ var (
procCopySid = modadvapi32.NewProc("CopySid")
procAllocateAndInitializeSid = modadvapi32.NewProc("AllocateAndInitializeSid")
procCreateWellKnownSid = modadvapi32.NewProc("CreateWellKnownSid")
procIsWellKnownSid = modadvapi32.NewProc("IsWellKnownSid")
procFreeSid = modadvapi32.NewProc("FreeSid")
procEqualSid = modadvapi32.NewProc("EqualSid")
procGetSidIdentifierAuthority = modadvapi32.NewProc("GetSidIdentifierAuthority")
procGetSidSubAuthorityCount = modadvapi32.NewProc("GetSidSubAuthorityCount")
procGetSidSubAuthority = modadvapi32.NewProc("GetSidSubAuthority")
procIsValidSid = modadvapi32.NewProc("IsValidSid")
procCheckTokenMembership = modadvapi32.NewProc("CheckTokenMembership")
procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken")
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
@@ -2827,6 +2832,12 @@ func createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, s
return
}
func isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) {
r0, _, _ := syscall.Syscall(procIsWellKnownSid.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(sidType), 0)
isWellKnown = r0 != 0
return
}
func FreeSid(sid *SID) (err error) {
r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
if r1 != 0 {
@@ -2845,6 +2856,30 @@ func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) {
return
}
func getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) {
r0, _, _ := syscall.Syscall(procGetSidIdentifierAuthority.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
authority = (*SidIdentifierAuthority)(unsafe.Pointer(r0))
return
}
func getSidSubAuthorityCount(sid *SID) (count *uint8) {
r0, _, _ := syscall.Syscall(procGetSidSubAuthorityCount.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
count = (*uint8)(unsafe.Pointer(r0))
return
}
func getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) {
r0, _, _ := syscall.Syscall(procGetSidSubAuthority.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(index), 0)
subAuthority = (*uint32)(unsafe.Pointer(r0))
return
}
func isValidSid(sid *SID) (isValid bool) {
r0, _, _ := syscall.Syscall(procIsValidSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
isValid = r0 != 0
return
}
func checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) {
r1, _, e1 := syscall.Syscall(procCheckTokenMembership.Addr(), 3, uintptr(tokenHandle), uintptr(unsafe.Pointer(sidToCheck)), uintptr(unsafe.Pointer(isMember)))
if r1 == 0 {