Browse Source

windows: add support for creating well known SIDs

The security API is already quite extensive, but for some strange
reason, this essential and useful function was left out of the initial
port. So, we add it here, along with the relevant constants and a test
case.

Change-Id: I99568703565addf15603480f11b0edafdfc1718f
Reviewed-on: https://go-review.googlesource.com/c/sys/+/167378
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Jason A. Donenfeld 6 years ago
parent
commit
a2f829d7f3
3 changed files with 180 additions and 0 deletions
  1. 153 0
      windows/security_windows.go
  2. 14 0
      windows/syscall_windows_test.go
  3. 13 0
      windows/zsyscall_windows.go

+ 153 - 0
windows/security_windows.go

@@ -169,6 +169,7 @@ const (
 //sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
 //sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
 //sys	AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid
+//sys	createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) = advapi32.CreateWellKnownSid
 //sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
 //sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
 
@@ -286,6 +287,158 @@ func (sid *SID) LookupAccount(system string) (account, domain string, accType ui
 	}
 }
 
+// Various types of pre-specified sids that can be synthesized at runtime.
+type WELL_KNOWN_SID_TYPE uint32
+
+const (
+	WinNullSid                                    = 0
+	WinWorldSid                                   = 1
+	WinLocalSid                                   = 2
+	WinCreatorOwnerSid                            = 3
+	WinCreatorGroupSid                            = 4
+	WinCreatorOwnerServerSid                      = 5
+	WinCreatorGroupServerSid                      = 6
+	WinNtAuthoritySid                             = 7
+	WinDialupSid                                  = 8
+	WinNetworkSid                                 = 9
+	WinBatchSid                                   = 10
+	WinInteractiveSid                             = 11
+	WinServiceSid                                 = 12
+	WinAnonymousSid                               = 13
+	WinProxySid                                   = 14
+	WinEnterpriseControllersSid                   = 15
+	WinSelfSid                                    = 16
+	WinAuthenticatedUserSid                       = 17
+	WinRestrictedCodeSid                          = 18
+	WinTerminalServerSid                          = 19
+	WinRemoteLogonIdSid                           = 20
+	WinLogonIdsSid                                = 21
+	WinLocalSystemSid                             = 22
+	WinLocalServiceSid                            = 23
+	WinNetworkServiceSid                          = 24
+	WinBuiltinDomainSid                           = 25
+	WinBuiltinAdministratorsSid                   = 26
+	WinBuiltinUsersSid                            = 27
+	WinBuiltinGuestsSid                           = 28
+	WinBuiltinPowerUsersSid                       = 29
+	WinBuiltinAccountOperatorsSid                 = 30
+	WinBuiltinSystemOperatorsSid                  = 31
+	WinBuiltinPrintOperatorsSid                   = 32
+	WinBuiltinBackupOperatorsSid                  = 33
+	WinBuiltinReplicatorSid                       = 34
+	WinBuiltinPreWindows2000CompatibleAccessSid   = 35
+	WinBuiltinRemoteDesktopUsersSid               = 36
+	WinBuiltinNetworkConfigurationOperatorsSid    = 37
+	WinAccountAdministratorSid                    = 38
+	WinAccountGuestSid                            = 39
+	WinAccountKrbtgtSid                           = 40
+	WinAccountDomainAdminsSid                     = 41
+	WinAccountDomainUsersSid                      = 42
+	WinAccountDomainGuestsSid                     = 43
+	WinAccountComputersSid                        = 44
+	WinAccountControllersSid                      = 45
+	WinAccountCertAdminsSid                       = 46
+	WinAccountSchemaAdminsSid                     = 47
+	WinAccountEnterpriseAdminsSid                 = 48
+	WinAccountPolicyAdminsSid                     = 49
+	WinAccountRasAndIasServersSid                 = 50
+	WinNTLMAuthenticationSid                      = 51
+	WinDigestAuthenticationSid                    = 52
+	WinSChannelAuthenticationSid                  = 53
+	WinThisOrganizationSid                        = 54
+	WinOtherOrganizationSid                       = 55
+	WinBuiltinIncomingForestTrustBuildersSid      = 56
+	WinBuiltinPerfMonitoringUsersSid              = 57
+	WinBuiltinPerfLoggingUsersSid                 = 58
+	WinBuiltinAuthorizationAccessSid              = 59
+	WinBuiltinTerminalServerLicenseServersSid     = 60
+	WinBuiltinDCOMUsersSid                        = 61
+	WinBuiltinIUsersSid                           = 62
+	WinIUserSid                                   = 63
+	WinBuiltinCryptoOperatorsSid                  = 64
+	WinUntrustedLabelSid                          = 65
+	WinLowLabelSid                                = 66
+	WinMediumLabelSid                             = 67
+	WinHighLabelSid                               = 68
+	WinSystemLabelSid                             = 69
+	WinWriteRestrictedCodeSid                     = 70
+	WinCreatorOwnerRightsSid                      = 71
+	WinCacheablePrincipalsGroupSid                = 72
+	WinNonCacheablePrincipalsGroupSid             = 73
+	WinEnterpriseReadonlyControllersSid           = 74
+	WinAccountReadonlyControllersSid              = 75
+	WinBuiltinEventLogReadersGroup                = 76
+	WinNewEnterpriseReadonlyControllersSid        = 77
+	WinBuiltinCertSvcDComAccessGroup              = 78
+	WinMediumPlusLabelSid                         = 79
+	WinLocalLogonSid                              = 80
+	WinConsoleLogonSid                            = 81
+	WinThisOrganizationCertificateSid             = 82
+	WinApplicationPackageAuthoritySid             = 83
+	WinBuiltinAnyPackageSid                       = 84
+	WinCapabilityInternetClientSid                = 85
+	WinCapabilityInternetClientServerSid          = 86
+	WinCapabilityPrivateNetworkClientServerSid    = 87
+	WinCapabilityPicturesLibrarySid               = 88
+	WinCapabilityVideosLibrarySid                 = 89
+	WinCapabilityMusicLibrarySid                  = 90
+	WinCapabilityDocumentsLibrarySid              = 91
+	WinCapabilitySharedUserCertificatesSid        = 92
+	WinCapabilityEnterpriseAuthenticationSid      = 93
+	WinCapabilityRemovableStorageSid              = 94
+	WinBuiltinRDSRemoteAccessServersSid           = 95
+	WinBuiltinRDSEndpointServersSid               = 96
+	WinBuiltinRDSManagementServersSid             = 97
+	WinUserModeDriversSid                         = 98
+	WinBuiltinHyperVAdminsSid                     = 99
+	WinAccountCloneableControllersSid             = 100
+	WinBuiltinAccessControlAssistanceOperatorsSid = 101
+	WinBuiltinRemoteManagementUsersSid            = 102
+	WinAuthenticationAuthorityAssertedSid         = 103
+	WinAuthenticationServiceAssertedSid           = 104
+	WinLocalAccountSid                            = 105
+	WinLocalAccountAndAdministratorSid            = 106
+	WinAccountProtectedUsersSid                   = 107
+	WinCapabilityAppointmentsSid                  = 108
+	WinCapabilityContactsSid                      = 109
+	WinAccountDefaultSystemManagedSid             = 110
+	WinBuiltinDefaultSystemManagedGroupSid        = 111
+	WinBuiltinStorageReplicaAdminsSid             = 112
+	WinAccountKeyAdminsSid                        = 113
+	WinAccountEnterpriseKeyAdminsSid              = 114
+	WinAuthenticationKeyTrustSid                  = 115
+	WinAuthenticationKeyPropertyMFASid            = 116
+	WinAuthenticationKeyPropertyAttestationSid    = 117
+	WinAuthenticationFreshKeyAuthSid              = 118
+	WinBuiltinDeviceOwnersSid                     = 119
+)
+
+// Creates a sid for a well-known predefined alias, generally using the constants of the form
+// Win*Sid, for the local machine.
+func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) {
+	return CreateWellKnownDomainSid(sidType, nil)
+}
+
+// Creates a sid for a well-known predefined alias, generally using the constants of the form
+// Win*Sid, for the domain specified by the domainSid parameter.
+func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) {
+	n := uint32(50)
+	for {
+		b := make([]byte, n)
+		sid := (*SID)(unsafe.Pointer(&b[0]))
+		err := createWellKnownSid(sidType, domainSid, sid, &n)
+		if err == nil {
+			return sid, nil
+		}
+		if err != ERROR_INSUFFICIENT_BUFFER {
+			return nil, err
+		}
+		if n <= uint32(len(b)) {
+			return nil, err
+		}
+	}
+}
+
 const (
 	// do not reorder
 	TOKEN_ASSIGN_PRIMARY = 1 << iota

+ 14 - 0
windows/syscall_windows_test.go

@@ -90,3 +90,17 @@ func TestTOKEN_ALL_ACCESS(t *testing.T) {
 		t.Errorf("TOKEN_ALL_ACCESS = %x, want 0xF01FF", windows.TOKEN_ALL_ACCESS)
 	}
 }
+
+func TestCreateWellKnownSid(t *testing.T) {
+	sid, err := windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
+	if err != nil {
+		t.Fatalf("Unable to create well known sid for administrators: %v", err)
+	}
+	sidStr, err := sid.String()
+	if err != nil {
+		t.Fatalf("Unable to convert sid into string: %v", err)
+	}
+	if sidStr != "S-1-5-32-544" {
+		t.Fatalf("Expecting administrators to be S-1-5-32-544, but found %s instead", sidStr)
+	}
+}

+ 13 - 0
windows/zsyscall_windows.go

@@ -246,6 +246,7 @@ var (
 	procGetLengthSid                       = modadvapi32.NewProc("GetLengthSid")
 	procCopySid                            = modadvapi32.NewProc("CopySid")
 	procAllocateAndInitializeSid           = modadvapi32.NewProc("AllocateAndInitializeSid")
+	procCreateWellKnownSid                 = modadvapi32.NewProc("CreateWellKnownSid")
 	procFreeSid                            = modadvapi32.NewProc("FreeSid")
 	procEqualSid                           = modadvapi32.NewProc("EqualSid")
 	procCheckTokenMembership               = modadvapi32.NewProc("CheckTokenMembership")
@@ -2654,6 +2655,18 @@ func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, s
 	return
 }
 
+func createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) {
+	r1, _, e1 := syscall.Syscall6(procCreateWellKnownSid.Addr(), 4, uintptr(sidType), uintptr(unsafe.Pointer(domainSid)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sizeSid)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = errnoErr(e1)
+		} else {
+			err = syscall.EINVAL
+		}
+	}
+	return
+}
+
 func FreeSid(sid *SID) (err error) {
 	r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
 	if r1 != 0 {