Source file src/cmd/vendor/golang.org/x/sys/windows/security_windows.go

     1  // Copyright 2012 The Go 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  
     5  package windows
     6  
     7  import (
     8  	"syscall"
     9  	"unsafe"
    10  
    11  	"golang.org/x/sys/internal/unsafeheader"
    12  )
    13  
    14  const (
    15  	NameUnknown          = 0
    16  	NameFullyQualifiedDN = 1
    17  	NameSamCompatible    = 2
    18  	NameDisplay          = 3
    19  	NameUniqueId         = 6
    20  	NameCanonical        = 7
    21  	NameUserPrincipal    = 8
    22  	NameCanonicalEx      = 9
    23  	NameServicePrincipal = 10
    24  	NameDnsDomain        = 12
    25  )
    26  
    27  // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
    28  // http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
    29  //sys	TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
    30  //sys	GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
    31  
    32  // TranslateAccountName converts a directory service
    33  // object name from one format to another.
    34  func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
    35  	u, e := UTF16PtrFromString(username)
    36  	if e != nil {
    37  		return "", e
    38  	}
    39  	n := uint32(50)
    40  	for {
    41  		b := make([]uint16, n)
    42  		e = TranslateName(u, from, to, &b[0], &n)
    43  		if e == nil {
    44  			return UTF16ToString(b[:n]), nil
    45  		}
    46  		if e != ERROR_INSUFFICIENT_BUFFER {
    47  			return "", e
    48  		}
    49  		if n <= uint32(len(b)) {
    50  			return "", e
    51  		}
    52  	}
    53  }
    54  
    55  const (
    56  	// do not reorder
    57  	NetSetupUnknownStatus = iota
    58  	NetSetupUnjoined
    59  	NetSetupWorkgroupName
    60  	NetSetupDomainName
    61  )
    62  
    63  type UserInfo10 struct {
    64  	Name       *uint16
    65  	Comment    *uint16
    66  	UsrComment *uint16
    67  	FullName   *uint16
    68  }
    69  
    70  //sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
    71  //sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
    72  //sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
    73  
    74  const (
    75  	// do not reorder
    76  	SidTypeUser = 1 + iota
    77  	SidTypeGroup
    78  	SidTypeDomain
    79  	SidTypeAlias
    80  	SidTypeWellKnownGroup
    81  	SidTypeDeletedAccount
    82  	SidTypeInvalid
    83  	SidTypeUnknown
    84  	SidTypeComputer
    85  	SidTypeLabel
    86  )
    87  
    88  type SidIdentifierAuthority struct {
    89  	Value [6]byte
    90  }
    91  
    92  var (
    93  	SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
    94  	SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
    95  	SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
    96  	SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
    97  	SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
    98  	SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
    99  	SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
   100  )
   101  
   102  const (
   103  	SECURITY_NULL_RID                   = 0
   104  	SECURITY_WORLD_RID                  = 0
   105  	SECURITY_LOCAL_RID                  = 0
   106  	SECURITY_CREATOR_OWNER_RID          = 0
   107  	SECURITY_CREATOR_GROUP_RID          = 1
   108  	SECURITY_DIALUP_RID                 = 1
   109  	SECURITY_NETWORK_RID                = 2
   110  	SECURITY_BATCH_RID                  = 3
   111  	SECURITY_INTERACTIVE_RID            = 4
   112  	SECURITY_LOGON_IDS_RID              = 5
   113  	SECURITY_SERVICE_RID                = 6
   114  	SECURITY_LOCAL_SYSTEM_RID           = 18
   115  	SECURITY_BUILTIN_DOMAIN_RID         = 32
   116  	SECURITY_PRINCIPAL_SELF_RID         = 10
   117  	SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
   118  	SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
   119  	SECURITY_LOGON_IDS_RID_COUNT        = 0x3
   120  	SECURITY_ANONYMOUS_LOGON_RID        = 0x7
   121  	SECURITY_PROXY_RID                  = 0x8
   122  	SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
   123  	SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
   124  	SECURITY_AUTHENTICATED_USER_RID     = 0xb
   125  	SECURITY_RESTRICTED_CODE_RID        = 0xc
   126  	SECURITY_NT_NON_UNIQUE_RID          = 0x15
   127  )
   128  
   129  // Predefined domain-relative RIDs for local groups.
   130  // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx
   131  const (
   132  	DOMAIN_ALIAS_RID_ADMINS                         = 0x220
   133  	DOMAIN_ALIAS_RID_USERS                          = 0x221
   134  	DOMAIN_ALIAS_RID_GUESTS                         = 0x222
   135  	DOMAIN_ALIAS_RID_POWER_USERS                    = 0x223
   136  	DOMAIN_ALIAS_RID_ACCOUNT_OPS                    = 0x224
   137  	DOMAIN_ALIAS_RID_SYSTEM_OPS                     = 0x225
   138  	DOMAIN_ALIAS_RID_PRINT_OPS                      = 0x226
   139  	DOMAIN_ALIAS_RID_BACKUP_OPS                     = 0x227
   140  	DOMAIN_ALIAS_RID_REPLICATOR                     = 0x228
   141  	DOMAIN_ALIAS_RID_RAS_SERVERS                    = 0x229
   142  	DOMAIN_ALIAS_RID_PREW2KCOMPACCESS               = 0x22a
   143  	DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS           = 0x22b
   144  	DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS      = 0x22c
   145  	DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d
   146  	DOMAIN_ALIAS_RID_MONITORING_USERS               = 0x22e
   147  	DOMAIN_ALIAS_RID_LOGGING_USERS                  = 0x22f
   148  	DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS            = 0x230
   149  	DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS             = 0x231
   150  	DOMAIN_ALIAS_RID_DCOM_USERS                     = 0x232
   151  	DOMAIN_ALIAS_RID_IUSERS                         = 0x238
   152  	DOMAIN_ALIAS_RID_CRYPTO_OPERATORS               = 0x239
   153  	DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP     = 0x23b
   154  	DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c
   155  	DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP        = 0x23d
   156  	DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP      = 0x23e
   157  )
   158  
   159  //sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
   160  //sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
   161  //sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
   162  //sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
   163  //sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
   164  //sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
   165  //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
   166  //sys	createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) = advapi32.CreateWellKnownSid
   167  //sys	isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) = advapi32.IsWellKnownSid
   168  //sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
   169  //sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
   170  //sys	getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) = advapi32.GetSidIdentifierAuthority
   171  //sys	getSidSubAuthorityCount(sid *SID) (count *uint8) = advapi32.GetSidSubAuthorityCount
   172  //sys	getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) = advapi32.GetSidSubAuthority
   173  //sys	isValidSid(sid *SID) (isValid bool) = advapi32.IsValidSid
   174  
   175  // The security identifier (SID) structure is a variable-length
   176  // structure used to uniquely identify users or groups.
   177  type SID struct{}
   178  
   179  // StringToSid converts a string-format security identifier
   180  // SID into a valid, functional SID.
   181  func StringToSid(s string) (*SID, error) {
   182  	var sid *SID
   183  	p, e := UTF16PtrFromString(s)
   184  	if e != nil {
   185  		return nil, e
   186  	}
   187  	e = ConvertStringSidToSid(p, &sid)
   188  	if e != nil {
   189  		return nil, e
   190  	}
   191  	defer LocalFree((Handle)(unsafe.Pointer(sid)))
   192  	return sid.Copy()
   193  }
   194  
   195  // LookupSID retrieves a security identifier SID for the account
   196  // and the name of the domain on which the account was found.
   197  // System specify target computer to search.
   198  func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
   199  	if len(account) == 0 {
   200  		return nil, "", 0, syscall.EINVAL
   201  	}
   202  	acc, e := UTF16PtrFromString(account)
   203  	if e != nil {
   204  		return nil, "", 0, e
   205  	}
   206  	var sys *uint16
   207  	if len(system) > 0 {
   208  		sys, e = UTF16PtrFromString(system)
   209  		if e != nil {
   210  			return nil, "", 0, e
   211  		}
   212  	}
   213  	n := uint32(50)
   214  	dn := uint32(50)
   215  	for {
   216  		b := make([]byte, n)
   217  		db := make([]uint16, dn)
   218  		sid = (*SID)(unsafe.Pointer(&b[0]))
   219  		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
   220  		if e == nil {
   221  			return sid, UTF16ToString(db), accType, nil
   222  		}
   223  		if e != ERROR_INSUFFICIENT_BUFFER {
   224  			return nil, "", 0, e
   225  		}
   226  		if n <= uint32(len(b)) {
   227  			return nil, "", 0, e
   228  		}
   229  	}
   230  }
   231  
   232  // String converts SID to a string format suitable for display, storage, or transmission.
   233  func (sid *SID) String() string {
   234  	var s *uint16
   235  	e := ConvertSidToStringSid(sid, &s)
   236  	if e != nil {
   237  		return ""
   238  	}
   239  	defer LocalFree((Handle)(unsafe.Pointer(s)))
   240  	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:])
   241  }
   242  
   243  // Len returns the length, in bytes, of a valid security identifier SID.
   244  func (sid *SID) Len() int {
   245  	return int(GetLengthSid(sid))
   246  }
   247  
   248  // Copy creates a duplicate of security identifier SID.
   249  func (sid *SID) Copy() (*SID, error) {
   250  	b := make([]byte, sid.Len())
   251  	sid2 := (*SID)(unsafe.Pointer(&b[0]))
   252  	e := CopySid(uint32(len(b)), sid2, sid)
   253  	if e != nil {
   254  		return nil, e
   255  	}
   256  	return sid2, nil
   257  }
   258  
   259  // IdentifierAuthority returns the identifier authority of the SID.
   260  func (sid *SID) IdentifierAuthority() SidIdentifierAuthority {
   261  	return *getSidIdentifierAuthority(sid)
   262  }
   263  
   264  // SubAuthorityCount returns the number of sub-authorities in the SID.
   265  func (sid *SID) SubAuthorityCount() uint8 {
   266  	return *getSidSubAuthorityCount(sid)
   267  }
   268  
   269  // SubAuthority returns the sub-authority of the SID as specified by
   270  // the index, which must be less than sid.SubAuthorityCount().
   271  func (sid *SID) SubAuthority(idx uint32) uint32 {
   272  	if idx >= uint32(sid.SubAuthorityCount()) {
   273  		panic("sub-authority index out of range")
   274  	}
   275  	return *getSidSubAuthority(sid, idx)
   276  }
   277  
   278  // IsValid returns whether the SID has a valid revision and length.
   279  func (sid *SID) IsValid() bool {
   280  	return isValidSid(sid)
   281  }
   282  
   283  // Equals compares two SIDs for equality.
   284  func (sid *SID) Equals(sid2 *SID) bool {
   285  	return EqualSid(sid, sid2)
   286  }
   287  
   288  // IsWellKnown determines whether the SID matches the well-known sidType.
   289  func (sid *SID) IsWellKnown(sidType WELL_KNOWN_SID_TYPE) bool {
   290  	return isWellKnownSid(sid, sidType)
   291  }
   292  
   293  // LookupAccount retrieves the name of the account for this SID
   294  // and the name of the first domain on which this SID is found.
   295  // System specify target computer to search for.
   296  func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
   297  	var sys *uint16
   298  	if len(system) > 0 {
   299  		sys, err = UTF16PtrFromString(system)
   300  		if err != nil {
   301  			return "", "", 0, err
   302  		}
   303  	}
   304  	n := uint32(50)
   305  	dn := uint32(50)
   306  	for {
   307  		b := make([]uint16, n)
   308  		db := make([]uint16, dn)
   309  		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
   310  		if e == nil {
   311  			return UTF16ToString(b), UTF16ToString(db), accType, nil
   312  		}
   313  		if e != ERROR_INSUFFICIENT_BUFFER {
   314  			return "", "", 0, e
   315  		}
   316  		if n <= uint32(len(b)) {
   317  			return "", "", 0, e
   318  		}
   319  	}
   320  }
   321  
   322  // Various types of pre-specified SIDs that can be synthesized and compared at runtime.
   323  type WELL_KNOWN_SID_TYPE uint32
   324  
   325  const (
   326  	WinNullSid                                    = 0
   327  	WinWorldSid                                   = 1
   328  	WinLocalSid                                   = 2
   329  	WinCreatorOwnerSid                            = 3
   330  	WinCreatorGroupSid                            = 4
   331  	WinCreatorOwnerServerSid                      = 5
   332  	WinCreatorGroupServerSid                      = 6
   333  	WinNtAuthoritySid                             = 7
   334  	WinDialupSid                                  = 8
   335  	WinNetworkSid                                 = 9
   336  	WinBatchSid                                   = 10
   337  	WinInteractiveSid                             = 11
   338  	WinServiceSid                                 = 12
   339  	WinAnonymousSid                               = 13
   340  	WinProxySid                                   = 14
   341  	WinEnterpriseControllersSid                   = 15
   342  	WinSelfSid                                    = 16
   343  	WinAuthenticatedUserSid                       = 17
   344  	WinRestrictedCodeSid                          = 18
   345  	WinTerminalServerSid                          = 19
   346  	WinRemoteLogonIdSid                           = 20
   347  	WinLogonIdsSid                                = 21
   348  	WinLocalSystemSid                             = 22
   349  	WinLocalServiceSid                            = 23
   350  	WinNetworkServiceSid                          = 24
   351  	WinBuiltinDomainSid                           = 25
   352  	WinBuiltinAdministratorsSid                   = 26
   353  	WinBuiltinUsersSid                            = 27
   354  	WinBuiltinGuestsSid                           = 28
   355  	WinBuiltinPowerUsersSid                       = 29
   356  	WinBuiltinAccountOperatorsSid                 = 30
   357  	WinBuiltinSystemOperatorsSid                  = 31
   358  	WinBuiltinPrintOperatorsSid                   = 32
   359  	WinBuiltinBackupOperatorsSid                  = 33
   360  	WinBuiltinReplicatorSid                       = 34
   361  	WinBuiltinPreWindows2000CompatibleAccessSid   = 35
   362  	WinBuiltinRemoteDesktopUsersSid               = 36
   363  	WinBuiltinNetworkConfigurationOperatorsSid    = 37
   364  	WinAccountAdministratorSid                    = 38
   365  	WinAccountGuestSid                            = 39
   366  	WinAccountKrbtgtSid                           = 40
   367  	WinAccountDomainAdminsSid                     = 41
   368  	WinAccountDomainUsersSid                      = 42
   369  	WinAccountDomainGuestsSid                     = 43
   370  	WinAccountComputersSid                        = 44
   371  	WinAccountControllersSid                      = 45
   372  	WinAccountCertAdminsSid                       = 46
   373  	WinAccountSchemaAdminsSid                     = 47
   374  	WinAccountEnterpriseAdminsSid                 = 48
   375  	WinAccountPolicyAdminsSid                     = 49
   376  	WinAccountRasAndIasServersSid                 = 50
   377  	WinNTLMAuthenticationSid                      = 51
   378  	WinDigestAuthenticationSid                    = 52
   379  	WinSChannelAuthenticationSid                  = 53
   380  	WinThisOrganizationSid                        = 54
   381  	WinOtherOrganizationSid                       = 55
   382  	WinBuiltinIncomingForestTrustBuildersSid      = 56
   383  	WinBuiltinPerfMonitoringUsersSid              = 57
   384  	WinBuiltinPerfLoggingUsersSid                 = 58
   385  	WinBuiltinAuthorizationAccessSid              = 59
   386  	WinBuiltinTerminalServerLicenseServersSid     = 60
   387  	WinBuiltinDCOMUsersSid                        = 61
   388  	WinBuiltinIUsersSid                           = 62
   389  	WinIUserSid                                   = 63
   390  	WinBuiltinCryptoOperatorsSid                  = 64
   391  	WinUntrustedLabelSid                          = 65
   392  	WinLowLabelSid                                = 66
   393  	WinMediumLabelSid                             = 67
   394  	WinHighLabelSid                               = 68
   395  	WinSystemLabelSid                             = 69
   396  	WinWriteRestrictedCodeSid                     = 70
   397  	WinCreatorOwnerRightsSid                      = 71
   398  	WinCacheablePrincipalsGroupSid                = 72
   399  	WinNonCacheablePrincipalsGroupSid             = 73
   400  	WinEnterpriseReadonlyControllersSid           = 74
   401  	WinAccountReadonlyControllersSid              = 75
   402  	WinBuiltinEventLogReadersGroup                = 76
   403  	WinNewEnterpriseReadonlyControllersSid        = 77
   404  	WinBuiltinCertSvcDComAccessGroup              = 78
   405  	WinMediumPlusLabelSid                         = 79
   406  	WinLocalLogonSid                              = 80
   407  	WinConsoleLogonSid                            = 81
   408  	WinThisOrganizationCertificateSid             = 82
   409  	WinApplicationPackageAuthoritySid             = 83
   410  	WinBuiltinAnyPackageSid                       = 84
   411  	WinCapabilityInternetClientSid                = 85
   412  	WinCapabilityInternetClientServerSid          = 86
   413  	WinCapabilityPrivateNetworkClientServerSid    = 87
   414  	WinCapabilityPicturesLibrarySid               = 88
   415  	WinCapabilityVideosLibrarySid                 = 89
   416  	WinCapabilityMusicLibrarySid                  = 90
   417  	WinCapabilityDocumentsLibrarySid              = 91
   418  	WinCapabilitySharedUserCertificatesSid        = 92
   419  	WinCapabilityEnterpriseAuthenticationSid      = 93
   420  	WinCapabilityRemovableStorageSid              = 94
   421  	WinBuiltinRDSRemoteAccessServersSid           = 95
   422  	WinBuiltinRDSEndpointServersSid               = 96
   423  	WinBuiltinRDSManagementServersSid             = 97
   424  	WinUserModeDriversSid                         = 98
   425  	WinBuiltinHyperVAdminsSid                     = 99
   426  	WinAccountCloneableControllersSid             = 100
   427  	WinBuiltinAccessControlAssistanceOperatorsSid = 101
   428  	WinBuiltinRemoteManagementUsersSid            = 102
   429  	WinAuthenticationAuthorityAssertedSid         = 103
   430  	WinAuthenticationServiceAssertedSid           = 104
   431  	WinLocalAccountSid                            = 105
   432  	WinLocalAccountAndAdministratorSid            = 106
   433  	WinAccountProtectedUsersSid                   = 107
   434  	WinCapabilityAppointmentsSid                  = 108
   435  	WinCapabilityContactsSid                      = 109
   436  	WinAccountDefaultSystemManagedSid             = 110
   437  	WinBuiltinDefaultSystemManagedGroupSid        = 111
   438  	WinBuiltinStorageReplicaAdminsSid             = 112
   439  	WinAccountKeyAdminsSid                        = 113
   440  	WinAccountEnterpriseKeyAdminsSid              = 114
   441  	WinAuthenticationKeyTrustSid                  = 115
   442  	WinAuthenticationKeyPropertyMFASid            = 116
   443  	WinAuthenticationKeyPropertyAttestationSid    = 117
   444  	WinAuthenticationFreshKeyAuthSid              = 118
   445  	WinBuiltinDeviceOwnersSid                     = 119
   446  )
   447  
   448  // Creates a SID for a well-known predefined alias, generally using the constants of the form
   449  // Win*Sid, for the local machine.
   450  func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) {
   451  	return CreateWellKnownDomainSid(sidType, nil)
   452  }
   453  
   454  // Creates a SID for a well-known predefined alias, generally using the constants of the form
   455  // Win*Sid, for the domain specified by the domainSid parameter.
   456  func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) {
   457  	n := uint32(50)
   458  	for {
   459  		b := make([]byte, n)
   460  		sid := (*SID)(unsafe.Pointer(&b[0]))
   461  		err := createWellKnownSid(sidType, domainSid, sid, &n)
   462  		if err == nil {
   463  			return sid, nil
   464  		}
   465  		if err != ERROR_INSUFFICIENT_BUFFER {
   466  			return nil, err
   467  		}
   468  		if n <= uint32(len(b)) {
   469  			return nil, err
   470  		}
   471  	}
   472  }
   473  
   474  const (
   475  	// do not reorder
   476  	TOKEN_ASSIGN_PRIMARY = 1 << iota
   477  	TOKEN_DUPLICATE
   478  	TOKEN_IMPERSONATE
   479  	TOKEN_QUERY
   480  	TOKEN_QUERY_SOURCE
   481  	TOKEN_ADJUST_PRIVILEGES
   482  	TOKEN_ADJUST_GROUPS
   483  	TOKEN_ADJUST_DEFAULT
   484  	TOKEN_ADJUST_SESSIONID
   485  
   486  	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
   487  		TOKEN_ASSIGN_PRIMARY |
   488  		TOKEN_DUPLICATE |
   489  		TOKEN_IMPERSONATE |
   490  		TOKEN_QUERY |
   491  		TOKEN_QUERY_SOURCE |
   492  		TOKEN_ADJUST_PRIVILEGES |
   493  		TOKEN_ADJUST_GROUPS |
   494  		TOKEN_ADJUST_DEFAULT |
   495  		TOKEN_ADJUST_SESSIONID
   496  	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
   497  	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
   498  		TOKEN_ADJUST_PRIVILEGES |
   499  		TOKEN_ADJUST_GROUPS |
   500  		TOKEN_ADJUST_DEFAULT
   501  	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
   502  )
   503  
   504  const (
   505  	// do not reorder
   506  	TokenUser = 1 + iota
   507  	TokenGroups
   508  	TokenPrivileges
   509  	TokenOwner
   510  	TokenPrimaryGroup
   511  	TokenDefaultDacl
   512  	TokenSource
   513  	TokenType
   514  	TokenImpersonationLevel
   515  	TokenStatistics
   516  	TokenRestrictedSids
   517  	TokenSessionId
   518  	TokenGroupsAndPrivileges
   519  	TokenSessionReference
   520  	TokenSandBoxInert
   521  	TokenAuditPolicy
   522  	TokenOrigin
   523  	TokenElevationType
   524  	TokenLinkedToken
   525  	TokenElevation
   526  	TokenHasRestrictions
   527  	TokenAccessInformation
   528  	TokenVirtualizationAllowed
   529  	TokenVirtualizationEnabled
   530  	TokenIntegrityLevel
   531  	TokenUIAccess
   532  	TokenMandatoryPolicy
   533  	TokenLogonSid
   534  	MaxTokenInfoClass
   535  )
   536  
   537  // Group attributes inside of Tokengroups.Groups[i].Attributes
   538  const (
   539  	SE_GROUP_MANDATORY          = 0x00000001
   540  	SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002
   541  	SE_GROUP_ENABLED            = 0x00000004
   542  	SE_GROUP_OWNER              = 0x00000008
   543  	SE_GROUP_USE_FOR_DENY_ONLY  = 0x00000010
   544  	SE_GROUP_INTEGRITY          = 0x00000020
   545  	SE_GROUP_INTEGRITY_ENABLED  = 0x00000040
   546  	SE_GROUP_LOGON_ID           = 0xC0000000
   547  	SE_GROUP_RESOURCE           = 0x20000000
   548  	SE_GROUP_VALID_ATTRIBUTES   = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED | SE_GROUP_OWNER | SE_GROUP_USE_FOR_DENY_ONLY | SE_GROUP_LOGON_ID | SE_GROUP_RESOURCE | SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED
   549  )
   550  
   551  // Privilege attributes
   552  const (
   553  	SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001
   554  	SE_PRIVILEGE_ENABLED            = 0x00000002
   555  	SE_PRIVILEGE_REMOVED            = 0x00000004
   556  	SE_PRIVILEGE_USED_FOR_ACCESS    = 0x80000000
   557  	SE_PRIVILEGE_VALID_ATTRIBUTES   = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_REMOVED | SE_PRIVILEGE_USED_FOR_ACCESS
   558  )
   559  
   560  // Token types
   561  const (
   562  	TokenPrimary       = 1
   563  	TokenImpersonation = 2
   564  )
   565  
   566  // Impersonation levels
   567  const (
   568  	SecurityAnonymous      = 0
   569  	SecurityIdentification = 1
   570  	SecurityImpersonation  = 2
   571  	SecurityDelegation     = 3
   572  )
   573  
   574  type LUID struct {
   575  	LowPart  uint32
   576  	HighPart int32
   577  }
   578  
   579  type LUIDAndAttributes struct {
   580  	Luid       LUID
   581  	Attributes uint32
   582  }
   583  
   584  type SIDAndAttributes struct {
   585  	Sid        *SID
   586  	Attributes uint32
   587  }
   588  
   589  type Tokenuser struct {
   590  	User SIDAndAttributes
   591  }
   592  
   593  type Tokenprimarygroup struct {
   594  	PrimaryGroup *SID
   595  }
   596  
   597  type Tokengroups struct {
   598  	GroupCount uint32
   599  	Groups     [1]SIDAndAttributes // Use AllGroups() for iterating.
   600  }
   601  
   602  // AllGroups returns a slice that can be used to iterate over the groups in g.
   603  func (g *Tokengroups) AllGroups() []SIDAndAttributes {
   604  	return (*[(1 << 28) - 1]SIDAndAttributes)(unsafe.Pointer(&g.Groups[0]))[:g.GroupCount:g.GroupCount]
   605  }
   606  
   607  type Tokenprivileges struct {
   608  	PrivilegeCount uint32
   609  	Privileges     [1]LUIDAndAttributes // Use AllPrivileges() for iterating.
   610  }
   611  
   612  // AllPrivileges returns a slice that can be used to iterate over the privileges in p.
   613  func (p *Tokenprivileges) AllPrivileges() []LUIDAndAttributes {
   614  	return (*[(1 << 27) - 1]LUIDAndAttributes)(unsafe.Pointer(&p.Privileges[0]))[:p.PrivilegeCount:p.PrivilegeCount]
   615  }
   616  
   617  type Tokenmandatorylabel struct {
   618  	Label SIDAndAttributes
   619  }
   620  
   621  func (tml *Tokenmandatorylabel) Size() uint32 {
   622  	return uint32(unsafe.Sizeof(Tokenmandatorylabel{})) + GetLengthSid(tml.Label.Sid)
   623  }
   624  
   625  // Authorization Functions
   626  //sys	checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership
   627  //sys	isTokenRestricted(tokenHandle Token) (ret bool, err error) [!failretval] = advapi32.IsTokenRestricted
   628  //sys	OpenProcessToken(process Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
   629  //sys	OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) = advapi32.OpenThreadToken
   630  //sys	ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf
   631  //sys	RevertToSelf() (err error) = advapi32.RevertToSelf
   632  //sys	SetThreadToken(thread *Handle, token Token) (err error) = advapi32.SetThreadToken
   633  //sys	LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW
   634  //sys	AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges
   635  //sys	AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) = advapi32.AdjustTokenGroups
   636  //sys	GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
   637  //sys	SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) = advapi32.SetTokenInformation
   638  //sys	DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) = advapi32.DuplicateTokenEx
   639  //sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
   640  //sys	getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
   641  //sys	getWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetWindowsDirectoryW
   642  //sys	getSystemWindowsDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemWindowsDirectoryW
   643  
   644  // An access token contains the security information for a logon session.
   645  // The system creates an access token when a user logs on, and every
   646  // process executed on behalf of the user has a copy of the token.
   647  // The token identifies the user, the user's groups, and the user's
   648  // privileges. The system uses the token to control access to securable
   649  // objects and to control the ability of the user to perform various
   650  // system-related operations on the local computer.
   651  type Token Handle
   652  
   653  // OpenCurrentProcessToken opens an access token associated with current
   654  // process with TOKEN_QUERY access. It is a real token that needs to be closed.
   655  //
   656  // Deprecated: Explicitly call OpenProcessToken(CurrentProcess(), ...)
   657  // with the desired access instead, or use GetCurrentProcessToken for a
   658  // TOKEN_QUERY token.
   659  func OpenCurrentProcessToken() (Token, error) {
   660  	var token Token
   661  	err := OpenProcessToken(CurrentProcess(), TOKEN_QUERY, &token)
   662  	return token, err
   663  }
   664  
   665  // GetCurrentProcessToken returns the access token associated with
   666  // the current process. It is a pseudo token that does not need
   667  // to be closed.
   668  func GetCurrentProcessToken() Token {
   669  	return Token(^uintptr(4 - 1))
   670  }
   671  
   672  // GetCurrentThreadToken return the access token associated with
   673  // the current thread. It is a pseudo token that does not need
   674  // to be closed.
   675  func GetCurrentThreadToken() Token {
   676  	return Token(^uintptr(5 - 1))
   677  }
   678  
   679  // GetCurrentThreadEffectiveToken returns the effective access token
   680  // associated with the current thread. It is a pseudo token that does
   681  // not need to be closed.
   682  func GetCurrentThreadEffectiveToken() Token {
   683  	return Token(^uintptr(6 - 1))
   684  }
   685  
   686  // Close releases access to access token.
   687  func (t Token) Close() error {
   688  	return CloseHandle(Handle(t))
   689  }
   690  
   691  // getInfo retrieves a specified type of information about an access token.
   692  func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
   693  	n := uint32(initSize)
   694  	for {
   695  		b := make([]byte, n)
   696  		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
   697  		if e == nil {
   698  			return unsafe.Pointer(&b[0]), nil
   699  		}
   700  		if e != ERROR_INSUFFICIENT_BUFFER {
   701  			return nil, e
   702  		}
   703  		if n <= uint32(len(b)) {
   704  			return nil, e
   705  		}
   706  	}
   707  }
   708  
   709  // GetTokenUser retrieves access token t user account information.
   710  func (t Token) GetTokenUser() (*Tokenuser, error) {
   711  	i, e := t.getInfo(TokenUser, 50)
   712  	if e != nil {
   713  		return nil, e
   714  	}
   715  	return (*Tokenuser)(i), nil
   716  }
   717  
   718  // GetTokenGroups retrieves group accounts associated with access token t.
   719  func (t Token) GetTokenGroups() (*Tokengroups, error) {
   720  	i, e := t.getInfo(TokenGroups, 50)
   721  	if e != nil {
   722  		return nil, e
   723  	}
   724  	return (*Tokengroups)(i), nil
   725  }
   726  
   727  // GetTokenPrimaryGroup retrieves access token t primary group information.
   728  // A pointer to a SID structure representing a group that will become
   729  // the primary group of any objects created by a process using this access token.
   730  func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
   731  	i, e := t.getInfo(TokenPrimaryGroup, 50)
   732  	if e != nil {
   733  		return nil, e
   734  	}
   735  	return (*Tokenprimarygroup)(i), nil
   736  }
   737  
   738  // GetUserProfileDirectory retrieves path to the
   739  // root directory of the access token t user's profile.
   740  func (t Token) GetUserProfileDirectory() (string, error) {
   741  	n := uint32(100)
   742  	for {
   743  		b := make([]uint16, n)
   744  		e := GetUserProfileDirectory(t, &b[0], &n)
   745  		if e == nil {
   746  			return UTF16ToString(b), nil
   747  		}
   748  		if e != ERROR_INSUFFICIENT_BUFFER {
   749  			return "", e
   750  		}
   751  		if n <= uint32(len(b)) {
   752  			return "", e
   753  		}
   754  	}
   755  }
   756  
   757  // IsElevated returns whether the current token is elevated from a UAC perspective.
   758  func (token Token) IsElevated() bool {
   759  	var isElevated uint32
   760  	var outLen uint32
   761  	err := GetTokenInformation(token, TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), uint32(unsafe.Sizeof(isElevated)), &outLen)
   762  	if err != nil {
   763  		return false
   764  	}
   765  	return outLen == uint32(unsafe.Sizeof(isElevated)) && isElevated != 0
   766  }
   767  
   768  // GetLinkedToken returns the linked token, which may be an elevated UAC token.
   769  func (token Token) GetLinkedToken() (Token, error) {
   770  	var linkedToken Token
   771  	var outLen uint32
   772  	err := GetTokenInformation(token, TokenLinkedToken, (*byte)(unsafe.Pointer(&linkedToken)), uint32(unsafe.Sizeof(linkedToken)), &outLen)
   773  	if err != nil {
   774  		return Token(0), err
   775  	}
   776  	return linkedToken, nil
   777  }
   778  
   779  // GetSystemDirectory retrieves the path to current location of the system
   780  // directory, which is typically, though not always, `C:\Windows\System32`.
   781  func GetSystemDirectory() (string, error) {
   782  	n := uint32(MAX_PATH)
   783  	for {
   784  		b := make([]uint16, n)
   785  		l, e := getSystemDirectory(&b[0], n)
   786  		if e != nil {
   787  			return "", e
   788  		}
   789  		if l <= n {
   790  			return UTF16ToString(b[:l]), nil
   791  		}
   792  		n = l
   793  	}
   794  }
   795  
   796  // GetWindowsDirectory retrieves the path to current location of the Windows
   797  // directory, which is typically, though not always, `C:\Windows`. This may
   798  // be a private user directory in the case that the application is running
   799  // under a terminal server.
   800  func GetWindowsDirectory() (string, error) {
   801  	n := uint32(MAX_PATH)
   802  	for {
   803  		b := make([]uint16, n)
   804  		l, e := getWindowsDirectory(&b[0], n)
   805  		if e != nil {
   806  			return "", e
   807  		}
   808  		if l <= n {
   809  			return UTF16ToString(b[:l]), nil
   810  		}
   811  		n = l
   812  	}
   813  }
   814  
   815  // GetSystemWindowsDirectory retrieves the path to current location of the
   816  // Windows directory, which is typically, though not always, `C:\Windows`.
   817  func GetSystemWindowsDirectory() (string, error) {
   818  	n := uint32(MAX_PATH)
   819  	for {
   820  		b := make([]uint16, n)
   821  		l, e := getSystemWindowsDirectory(&b[0], n)
   822  		if e != nil {
   823  			return "", e
   824  		}
   825  		if l <= n {
   826  			return UTF16ToString(b[:l]), nil
   827  		}
   828  		n = l
   829  	}
   830  }
   831  
   832  // IsMember reports whether the access token t is a member of the provided SID.
   833  func (t Token) IsMember(sid *SID) (bool, error) {
   834  	var b int32
   835  	if e := checkTokenMembership(t, sid, &b); e != nil {
   836  		return false, e
   837  	}
   838  	return b != 0, nil
   839  }
   840  
   841  // IsRestricted reports whether the access token t is a restricted token.
   842  func (t Token) IsRestricted() (isRestricted bool, err error) {
   843  	isRestricted, err = isTokenRestricted(t)
   844  	if !isRestricted && err == syscall.EINVAL {
   845  		// If err is EINVAL, this returned ERROR_SUCCESS indicating a non-restricted token.
   846  		err = nil
   847  	}
   848  	return
   849  }
   850  
   851  const (
   852  	WTS_CONSOLE_CONNECT        = 0x1
   853  	WTS_CONSOLE_DISCONNECT     = 0x2
   854  	WTS_REMOTE_CONNECT         = 0x3
   855  	WTS_REMOTE_DISCONNECT      = 0x4
   856  	WTS_SESSION_LOGON          = 0x5
   857  	WTS_SESSION_LOGOFF         = 0x6
   858  	WTS_SESSION_LOCK           = 0x7
   859  	WTS_SESSION_UNLOCK         = 0x8
   860  	WTS_SESSION_REMOTE_CONTROL = 0x9
   861  	WTS_SESSION_CREATE         = 0xa
   862  	WTS_SESSION_TERMINATE      = 0xb
   863  )
   864  
   865  const (
   866  	WTSActive       = 0
   867  	WTSConnected    = 1
   868  	WTSConnectQuery = 2
   869  	WTSShadow       = 3
   870  	WTSDisconnected = 4
   871  	WTSIdle         = 5
   872  	WTSListen       = 6
   873  	WTSReset        = 7
   874  	WTSDown         = 8
   875  	WTSInit         = 9
   876  )
   877  
   878  type WTSSESSION_NOTIFICATION struct {
   879  	Size      uint32
   880  	SessionID uint32
   881  }
   882  
   883  type WTS_SESSION_INFO struct {
   884  	SessionID         uint32
   885  	WindowStationName *uint16
   886  	State             uint32
   887  }
   888  
   889  //sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken
   890  //sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW
   891  //sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory
   892  //sys WTSGetActiveConsoleSessionId() (sessionID uint32)
   893  
   894  type ACL struct {
   895  	aclRevision byte
   896  	sbz1        byte
   897  	aclSize     uint16
   898  	aceCount    uint16
   899  	sbz2        uint16
   900  }
   901  
   902  type SECURITY_DESCRIPTOR struct {
   903  	revision byte
   904  	sbz1     byte
   905  	control  SECURITY_DESCRIPTOR_CONTROL
   906  	owner    *SID
   907  	group    *SID
   908  	sacl     *ACL
   909  	dacl     *ACL
   910  }
   911  
   912  type SECURITY_QUALITY_OF_SERVICE struct {
   913  	Length              uint32
   914  	ImpersonationLevel  uint32
   915  	ContextTrackingMode byte
   916  	EffectiveOnly       byte
   917  }
   918  
   919  // Constants for the ContextTrackingMode field of SECURITY_QUALITY_OF_SERVICE.
   920  const (
   921  	SECURITY_STATIC_TRACKING  = 0
   922  	SECURITY_DYNAMIC_TRACKING = 1
   923  )
   924  
   925  type SecurityAttributes struct {
   926  	Length             uint32
   927  	SecurityDescriptor *SECURITY_DESCRIPTOR
   928  	InheritHandle      uint32
   929  }
   930  
   931  type SE_OBJECT_TYPE uint32
   932  
   933  // Constants for type SE_OBJECT_TYPE
   934  const (
   935  	SE_UNKNOWN_OBJECT_TYPE     = 0
   936  	SE_FILE_OBJECT             = 1
   937  	SE_SERVICE                 = 2
   938  	SE_PRINTER                 = 3
   939  	SE_REGISTRY_KEY            = 4
   940  	SE_LMSHARE                 = 5
   941  	SE_KERNEL_OBJECT           = 6
   942  	SE_WINDOW_OBJECT           = 7
   943  	SE_DS_OBJECT               = 8
   944  	SE_DS_OBJECT_ALL           = 9
   945  	SE_PROVIDER_DEFINED_OBJECT = 10
   946  	SE_WMIGUID_OBJECT          = 11
   947  	SE_REGISTRY_WOW64_32KEY    = 12
   948  	SE_REGISTRY_WOW64_64KEY    = 13
   949  )
   950  
   951  type SECURITY_INFORMATION uint32
   952  
   953  // Constants for type SECURITY_INFORMATION
   954  const (
   955  	OWNER_SECURITY_INFORMATION            = 0x00000001
   956  	GROUP_SECURITY_INFORMATION            = 0x00000002
   957  	DACL_SECURITY_INFORMATION             = 0x00000004
   958  	SACL_SECURITY_INFORMATION             = 0x00000008
   959  	LABEL_SECURITY_INFORMATION            = 0x00000010
   960  	ATTRIBUTE_SECURITY_INFORMATION        = 0x00000020
   961  	SCOPE_SECURITY_INFORMATION            = 0x00000040
   962  	BACKUP_SECURITY_INFORMATION           = 0x00010000
   963  	PROTECTED_DACL_SECURITY_INFORMATION   = 0x80000000
   964  	PROTECTED_SACL_SECURITY_INFORMATION   = 0x40000000
   965  	UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000
   966  	UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000
   967  )
   968  
   969  type SECURITY_DESCRIPTOR_CONTROL uint16
   970  
   971  // Constants for type SECURITY_DESCRIPTOR_CONTROL
   972  const (
   973  	SE_OWNER_DEFAULTED       = 0x0001
   974  	SE_GROUP_DEFAULTED       = 0x0002
   975  	SE_DACL_PRESENT          = 0x0004
   976  	SE_DACL_DEFAULTED        = 0x0008
   977  	SE_SACL_PRESENT          = 0x0010
   978  	SE_SACL_DEFAULTED        = 0x0020
   979  	SE_DACL_AUTO_INHERIT_REQ = 0x0100
   980  	SE_SACL_AUTO_INHERIT_REQ = 0x0200
   981  	SE_DACL_AUTO_INHERITED   = 0x0400
   982  	SE_SACL_AUTO_INHERITED   = 0x0800
   983  	SE_DACL_PROTECTED        = 0x1000
   984  	SE_SACL_PROTECTED        = 0x2000
   985  	SE_RM_CONTROL_VALID      = 0x4000
   986  	SE_SELF_RELATIVE         = 0x8000
   987  )
   988  
   989  type ACCESS_MASK uint32
   990  
   991  // Constants for type ACCESS_MASK
   992  const (
   993  	DELETE                   = 0x00010000
   994  	READ_CONTROL             = 0x00020000
   995  	WRITE_DAC                = 0x00040000
   996  	WRITE_OWNER              = 0x00080000
   997  	SYNCHRONIZE              = 0x00100000
   998  	STANDARD_RIGHTS_REQUIRED = 0x000F0000
   999  	STANDARD_RIGHTS_READ     = READ_CONTROL
  1000  	STANDARD_RIGHTS_WRITE    = READ_CONTROL
  1001  	STANDARD_RIGHTS_EXECUTE  = READ_CONTROL
  1002  	STANDARD_RIGHTS_ALL      = 0x001F0000
  1003  	SPECIFIC_RIGHTS_ALL      = 0x0000FFFF
  1004  	ACCESS_SYSTEM_SECURITY   = 0x01000000
  1005  	MAXIMUM_ALLOWED          = 0x02000000
  1006  	GENERIC_READ             = 0x80000000
  1007  	GENERIC_WRITE            = 0x40000000
  1008  	GENERIC_EXECUTE          = 0x20000000
  1009  	GENERIC_ALL              = 0x10000000
  1010  )
  1011  
  1012  type ACCESS_MODE uint32
  1013  
  1014  // Constants for type ACCESS_MODE
  1015  const (
  1016  	NOT_USED_ACCESS   = 0
  1017  	GRANT_ACCESS      = 1
  1018  	SET_ACCESS        = 2
  1019  	DENY_ACCESS       = 3
  1020  	REVOKE_ACCESS     = 4
  1021  	SET_AUDIT_SUCCESS = 5
  1022  	SET_AUDIT_FAILURE = 6
  1023  )
  1024  
  1025  // Constants for AceFlags and Inheritance fields
  1026  const (
  1027  	NO_INHERITANCE                     = 0x0
  1028  	SUB_OBJECTS_ONLY_INHERIT           = 0x1
  1029  	SUB_CONTAINERS_ONLY_INHERIT        = 0x2
  1030  	SUB_CONTAINERS_AND_OBJECTS_INHERIT = 0x3
  1031  	INHERIT_NO_PROPAGATE               = 0x4
  1032  	INHERIT_ONLY                       = 0x8
  1033  	INHERITED_ACCESS_ENTRY             = 0x10
  1034  	INHERITED_PARENT                   = 0x10000000
  1035  	INHERITED_GRANDPARENT              = 0x20000000
  1036  	OBJECT_INHERIT_ACE                 = 0x1
  1037  	CONTAINER_INHERIT_ACE              = 0x2
  1038  	NO_PROPAGATE_INHERIT_ACE           = 0x4
  1039  	INHERIT_ONLY_ACE                   = 0x8
  1040  	INHERITED_ACE                      = 0x10
  1041  	VALID_INHERIT_FLAGS                = 0x1F
  1042  )
  1043  
  1044  type MULTIPLE_TRUSTEE_OPERATION uint32
  1045  
  1046  // Constants for MULTIPLE_TRUSTEE_OPERATION
  1047  const (
  1048  	NO_MULTIPLE_TRUSTEE    = 0
  1049  	TRUSTEE_IS_IMPERSONATE = 1
  1050  )
  1051  
  1052  type TRUSTEE_FORM uint32
  1053  
  1054  // Constants for TRUSTEE_FORM
  1055  const (
  1056  	TRUSTEE_IS_SID              = 0
  1057  	TRUSTEE_IS_NAME             = 1
  1058  	TRUSTEE_BAD_FORM            = 2
  1059  	TRUSTEE_IS_OBJECTS_AND_SID  = 3
  1060  	TRUSTEE_IS_OBJECTS_AND_NAME = 4
  1061  )
  1062  
  1063  type TRUSTEE_TYPE uint32
  1064  
  1065  // Constants for TRUSTEE_TYPE
  1066  const (
  1067  	TRUSTEE_IS_UNKNOWN          = 0
  1068  	TRUSTEE_IS_USER             = 1
  1069  	TRUSTEE_IS_GROUP            = 2
  1070  	TRUSTEE_IS_DOMAIN           = 3
  1071  	TRUSTEE_IS_ALIAS            = 4
  1072  	TRUSTEE_IS_WELL_KNOWN_GROUP = 5
  1073  	TRUSTEE_IS_DELETED          = 6
  1074  	TRUSTEE_IS_INVALID          = 7
  1075  	TRUSTEE_IS_COMPUTER         = 8
  1076  )
  1077  
  1078  // Constants for ObjectsPresent field
  1079  const (
  1080  	ACE_OBJECT_TYPE_PRESENT           = 0x1
  1081  	ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x2
  1082  )
  1083  
  1084  type EXPLICIT_ACCESS struct {
  1085  	AccessPermissions ACCESS_MASK
  1086  	AccessMode        ACCESS_MODE
  1087  	Inheritance       uint32
  1088  	Trustee           TRUSTEE
  1089  }
  1090  
  1091  // This type is the union inside of TRUSTEE and must be created using one of the TrusteeValueFrom* functions.
  1092  type TrusteeValue uintptr
  1093  
  1094  func TrusteeValueFromString(str string) TrusteeValue {
  1095  	return TrusteeValue(unsafe.Pointer(StringToUTF16Ptr(str)))
  1096  }
  1097  func TrusteeValueFromSID(sid *SID) TrusteeValue {
  1098  	return TrusteeValue(unsafe.Pointer(sid))
  1099  }
  1100  func TrusteeValueFromObjectsAndSid(objectsAndSid *OBJECTS_AND_SID) TrusteeValue {
  1101  	return TrusteeValue(unsafe.Pointer(objectsAndSid))
  1102  }
  1103  func TrusteeValueFromObjectsAndName(objectsAndName *OBJECTS_AND_NAME) TrusteeValue {
  1104  	return TrusteeValue(unsafe.Pointer(objectsAndName))
  1105  }
  1106  
  1107  type TRUSTEE struct {
  1108  	MultipleTrustee          *TRUSTEE
  1109  	MultipleTrusteeOperation MULTIPLE_TRUSTEE_OPERATION
  1110  	TrusteeForm              TRUSTEE_FORM
  1111  	TrusteeType              TRUSTEE_TYPE
  1112  	TrusteeValue             TrusteeValue
  1113  }
  1114  
  1115  type OBJECTS_AND_SID struct {
  1116  	ObjectsPresent          uint32
  1117  	ObjectTypeGuid          GUID
  1118  	InheritedObjectTypeGuid GUID
  1119  	Sid                     *SID
  1120  }
  1121  
  1122  type OBJECTS_AND_NAME struct {
  1123  	ObjectsPresent          uint32
  1124  	ObjectType              SE_OBJECT_TYPE
  1125  	ObjectTypeName          *uint16
  1126  	InheritedObjectTypeName *uint16
  1127  	Name                    *uint16
  1128  }
  1129  
  1130  //sys	getSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) = advapi32.GetSecurityInfo
  1131  //sys	SetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetSecurityInfo
  1132  //sys	getNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner **SID, group **SID, dacl **ACL, sacl **ACL, sd **SECURITY_DESCRIPTOR) (ret error) = advapi32.GetNamedSecurityInfoW
  1133  //sys	SetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION, owner *SID, group *SID, dacl *ACL, sacl *ACL) (ret error) = advapi32.SetNamedSecurityInfoW
  1134  //sys	SetKernelObjectSecurity(handle Handle, securityInformation SECURITY_INFORMATION, securityDescriptor *SECURITY_DESCRIPTOR) (err error) = advapi32.SetKernelObjectSecurity
  1135  
  1136  //sys	buildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, countAccessEntries uint32, accessEntries *EXPLICIT_ACCESS, countAuditEntries uint32, auditEntries *EXPLICIT_ACCESS, oldSecurityDescriptor *SECURITY_DESCRIPTOR, sizeNewSecurityDescriptor *uint32, newSecurityDescriptor **SECURITY_DESCRIPTOR) (ret error) = advapi32.BuildSecurityDescriptorW
  1137  //sys	initializeSecurityDescriptor(absoluteSD *SECURITY_DESCRIPTOR, revision uint32) (err error) = advapi32.InitializeSecurityDescriptor
  1138  
  1139  //sys	getSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, control *SECURITY_DESCRIPTOR_CONTROL, revision *uint32) (err error) = advapi32.GetSecurityDescriptorControl
  1140  //sys	getSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent *bool, dacl **ACL, daclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorDacl
  1141  //sys	getSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent *bool, sacl **ACL, saclDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorSacl
  1142  //sys	getSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner **SID, ownerDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorOwner
  1143  //sys	getSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group **SID, groupDefaulted *bool) (err error) = advapi32.GetSecurityDescriptorGroup
  1144  //sys	getSecurityDescriptorLength(sd *SECURITY_DESCRIPTOR) (len uint32) = advapi32.GetSecurityDescriptorLength
  1145  //sys	getSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) (ret error) [failretval!=0] = advapi32.GetSecurityDescriptorRMControl
  1146  //sys	isValidSecurityDescriptor(sd *SECURITY_DESCRIPTOR) (isValid bool) = advapi32.IsValidSecurityDescriptor
  1147  
  1148  //sys	setSecurityDescriptorControl(sd *SECURITY_DESCRIPTOR, controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) (err error) = advapi32.SetSecurityDescriptorControl
  1149  //sys	setSecurityDescriptorDacl(sd *SECURITY_DESCRIPTOR, daclPresent bool, dacl *ACL, daclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorDacl
  1150  //sys	setSecurityDescriptorSacl(sd *SECURITY_DESCRIPTOR, saclPresent bool, sacl *ACL, saclDefaulted bool) (err error) = advapi32.SetSecurityDescriptorSacl
  1151  //sys	setSecurityDescriptorOwner(sd *SECURITY_DESCRIPTOR, owner *SID, ownerDefaulted bool) (err error) = advapi32.SetSecurityDescriptorOwner
  1152  //sys	setSecurityDescriptorGroup(sd *SECURITY_DESCRIPTOR, group *SID, groupDefaulted bool) (err error) = advapi32.SetSecurityDescriptorGroup
  1153  //sys	setSecurityDescriptorRMControl(sd *SECURITY_DESCRIPTOR, rmControl *uint8) = advapi32.SetSecurityDescriptorRMControl
  1154  
  1155  //sys	convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd **SECURITY_DESCRIPTOR, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
  1156  //sys	convertSecurityDescriptorToStringSecurityDescriptor(sd *SECURITY_DESCRIPTOR, revision uint32, securityInformation SECURITY_INFORMATION, str **uint16, strLen *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
  1157  
  1158  //sys	makeAbsoluteSD(selfRelativeSD *SECURITY_DESCRIPTOR, absoluteSD *SECURITY_DESCRIPTOR, absoluteSDSize *uint32, dacl *ACL, daclSize *uint32, sacl *ACL, saclSize *uint32, owner *SID, ownerSize *uint32, group *SID, groupSize *uint32) (err error) = advapi32.MakeAbsoluteSD
  1159  //sys	makeSelfRelativeSD(absoluteSD *SECURITY_DESCRIPTOR, selfRelativeSD *SECURITY_DESCRIPTOR, selfRelativeSDSize *uint32) (err error) = advapi32.MakeSelfRelativeSD
  1160  
  1161  //sys	setEntriesInAcl(countExplicitEntries uint32, explicitEntries *EXPLICIT_ACCESS, oldACL *ACL, newACL **ACL) (ret error) = advapi32.SetEntriesInAclW
  1162  
  1163  // Control returns the security descriptor control bits.
  1164  func (sd *SECURITY_DESCRIPTOR) Control() (control SECURITY_DESCRIPTOR_CONTROL, revision uint32, err error) {
  1165  	err = getSecurityDescriptorControl(sd, &control, &revision)
  1166  	return
  1167  }
  1168  
  1169  // SetControl sets the security descriptor control bits.
  1170  func (sd *SECURITY_DESCRIPTOR) SetControl(controlBitsOfInterest SECURITY_DESCRIPTOR_CONTROL, controlBitsToSet SECURITY_DESCRIPTOR_CONTROL) error {
  1171  	return setSecurityDescriptorControl(sd, controlBitsOfInterest, controlBitsToSet)
  1172  }
  1173  
  1174  // RMControl returns the security descriptor resource manager control bits.
  1175  func (sd *SECURITY_DESCRIPTOR) RMControl() (control uint8, err error) {
  1176  	err = getSecurityDescriptorRMControl(sd, &control)
  1177  	return
  1178  }
  1179  
  1180  // SetRMControl sets the security descriptor resource manager control bits.
  1181  func (sd *SECURITY_DESCRIPTOR) SetRMControl(rmControl uint8) {
  1182  	setSecurityDescriptorRMControl(sd, &rmControl)
  1183  }
  1184  
  1185  // DACL returns the security descriptor DACL and whether it was defaulted. The dacl return value may be nil
  1186  // if a DACL exists but is an "empty DACL", meaning fully permissive. If the DACL does not exist, err returns
  1187  // ERROR_OBJECT_NOT_FOUND.
  1188  func (sd *SECURITY_DESCRIPTOR) DACL() (dacl *ACL, defaulted bool, err error) {
  1189  	var present bool
  1190  	err = getSecurityDescriptorDacl(sd, &present, &dacl, &defaulted)
  1191  	if !present {
  1192  		err = ERROR_OBJECT_NOT_FOUND
  1193  	}
  1194  	return
  1195  }
  1196  
  1197  // SetDACL sets the absolute security descriptor DACL.
  1198  func (absoluteSD *SECURITY_DESCRIPTOR) SetDACL(dacl *ACL, present, defaulted bool) error {
  1199  	return setSecurityDescriptorDacl(absoluteSD, present, dacl, defaulted)
  1200  }
  1201  
  1202  // SACL returns the security descriptor SACL and whether it was defaulted. The sacl return value may be nil
  1203  // if a SACL exists but is an "empty SACL", meaning fully permissive. If the SACL does not exist, err returns
  1204  // ERROR_OBJECT_NOT_FOUND.
  1205  func (sd *SECURITY_DESCRIPTOR) SACL() (sacl *ACL, defaulted bool, err error) {
  1206  	var present bool
  1207  	err = getSecurityDescriptorSacl(sd, &present, &sacl, &defaulted)
  1208  	if !present {
  1209  		err = ERROR_OBJECT_NOT_FOUND
  1210  	}
  1211  	return
  1212  }
  1213  
  1214  // SetSACL sets the absolute security descriptor SACL.
  1215  func (absoluteSD *SECURITY_DESCRIPTOR) SetSACL(sacl *ACL, present, defaulted bool) error {
  1216  	return setSecurityDescriptorSacl(absoluteSD, present, sacl, defaulted)
  1217  }
  1218  
  1219  // Owner returns the security descriptor owner and whether it was defaulted.
  1220  func (sd *SECURITY_DESCRIPTOR) Owner() (owner *SID, defaulted bool, err error) {
  1221  	err = getSecurityDescriptorOwner(sd, &owner, &defaulted)
  1222  	return
  1223  }
  1224  
  1225  // SetOwner sets the absolute security descriptor owner.
  1226  func (absoluteSD *SECURITY_DESCRIPTOR) SetOwner(owner *SID, defaulted bool) error {
  1227  	return setSecurityDescriptorOwner(absoluteSD, owner, defaulted)
  1228  }
  1229  
  1230  // Group returns the security descriptor group and whether it was defaulted.
  1231  func (sd *SECURITY_DESCRIPTOR) Group() (group *SID, defaulted bool, err error) {
  1232  	err = getSecurityDescriptorGroup(sd, &group, &defaulted)
  1233  	return
  1234  }
  1235  
  1236  // SetGroup sets the absolute security descriptor owner.
  1237  func (absoluteSD *SECURITY_DESCRIPTOR) SetGroup(group *SID, defaulted bool) error {
  1238  	return setSecurityDescriptorGroup(absoluteSD, group, defaulted)
  1239  }
  1240  
  1241  // Length returns the length of the security descriptor.
  1242  func (sd *SECURITY_DESCRIPTOR) Length() uint32 {
  1243  	return getSecurityDescriptorLength(sd)
  1244  }
  1245  
  1246  // IsValid returns whether the security descriptor is valid.
  1247  func (sd *SECURITY_DESCRIPTOR) IsValid() bool {
  1248  	return isValidSecurityDescriptor(sd)
  1249  }
  1250  
  1251  // String returns the SDDL form of the security descriptor, with a function signature that can be
  1252  // used with %v formatting directives.
  1253  func (sd *SECURITY_DESCRIPTOR) String() string {
  1254  	var sddl *uint16
  1255  	err := convertSecurityDescriptorToStringSecurityDescriptor(sd, 1, 0xff, &sddl, nil)
  1256  	if err != nil {
  1257  		return ""
  1258  	}
  1259  	defer LocalFree(Handle(unsafe.Pointer(sddl)))
  1260  	return UTF16PtrToString(sddl)
  1261  }
  1262  
  1263  // ToAbsolute converts a self-relative security descriptor into an absolute one.
  1264  func (selfRelativeSD *SECURITY_DESCRIPTOR) ToAbsolute() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
  1265  	control, _, err := selfRelativeSD.Control()
  1266  	if err != nil {
  1267  		return
  1268  	}
  1269  	if control&SE_SELF_RELATIVE == 0 {
  1270  		err = ERROR_INVALID_PARAMETER
  1271  		return
  1272  	}
  1273  	var absoluteSDSize, daclSize, saclSize, ownerSize, groupSize uint32
  1274  	err = makeAbsoluteSD(selfRelativeSD, nil, &absoluteSDSize,
  1275  		nil, &daclSize, nil, &saclSize, nil, &ownerSize, nil, &groupSize)
  1276  	switch err {
  1277  	case ERROR_INSUFFICIENT_BUFFER:
  1278  	case nil:
  1279  		// makeAbsoluteSD is expected to fail, but it succeeds.
  1280  		return nil, ERROR_INTERNAL_ERROR
  1281  	default:
  1282  		return nil, err
  1283  	}
  1284  	if absoluteSDSize > 0 {
  1285  		absoluteSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0]))
  1286  	}
  1287  	var (
  1288  		dacl  *ACL
  1289  		sacl  *ACL
  1290  		owner *SID
  1291  		group *SID
  1292  	)
  1293  	if daclSize > 0 {
  1294  		dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0]))
  1295  	}
  1296  	if saclSize > 0 {
  1297  		sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0]))
  1298  	}
  1299  	if ownerSize > 0 {
  1300  		owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0]))
  1301  	}
  1302  	if groupSize > 0 {
  1303  		group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0]))
  1304  	}
  1305  	err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
  1306  		dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
  1307  	return
  1308  }
  1309  
  1310  // ToSelfRelative converts an absolute security descriptor into a self-relative one.
  1311  func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURITY_DESCRIPTOR, err error) {
  1312  	control, _, err := absoluteSD.Control()
  1313  	if err != nil {
  1314  		return
  1315  	}
  1316  	if control&SE_SELF_RELATIVE != 0 {
  1317  		err = ERROR_INVALID_PARAMETER
  1318  		return
  1319  	}
  1320  	var selfRelativeSDSize uint32
  1321  	err = makeSelfRelativeSD(absoluteSD, nil, &selfRelativeSDSize)
  1322  	switch err {
  1323  	case ERROR_INSUFFICIENT_BUFFER:
  1324  	case nil:
  1325  		// makeSelfRelativeSD is expected to fail, but it succeeds.
  1326  		return nil, ERROR_INTERNAL_ERROR
  1327  	default:
  1328  		return nil, err
  1329  	}
  1330  	if selfRelativeSDSize > 0 {
  1331  		selfRelativeSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, selfRelativeSDSize)[0]))
  1332  	}
  1333  	err = makeSelfRelativeSD(absoluteSD, selfRelativeSD, &selfRelativeSDSize)
  1334  	return
  1335  }
  1336  
  1337  func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {
  1338  	sdLen := int(selfRelativeSD.Length())
  1339  	const min = int(unsafe.Sizeof(SECURITY_DESCRIPTOR{}))
  1340  	if sdLen < min {
  1341  		sdLen = min
  1342  	}
  1343  
  1344  	var src []byte
  1345  	h := (*unsafeheader.Slice)(unsafe.Pointer(&src))
  1346  	h.Data = unsafe.Pointer(selfRelativeSD)
  1347  	h.Len = sdLen
  1348  	h.Cap = sdLen
  1349  
  1350  	const psize = int(unsafe.Sizeof(uintptr(0)))
  1351  
  1352  	var dst []byte
  1353  	h = (*unsafeheader.Slice)(unsafe.Pointer(&dst))
  1354  	alloc := make([]uintptr, (sdLen+psize-1)/psize)
  1355  	h.Data = (*unsafeheader.Slice)(unsafe.Pointer(&alloc)).Data
  1356  	h.Len = sdLen
  1357  	h.Cap = sdLen
  1358  
  1359  	copy(dst, src)
  1360  	return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
  1361  }
  1362  
  1363  // SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a
  1364  // self-relative security descriptor object allocated on the Go heap.
  1365  func SecurityDescriptorFromString(sddl string) (sd *SECURITY_DESCRIPTOR, err error) {
  1366  	var winHeapSD *SECURITY_DESCRIPTOR
  1367  	err = convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &winHeapSD, nil)
  1368  	if err != nil {
  1369  		return
  1370  	}
  1371  	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
  1372  	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
  1373  }
  1374  
  1375  // GetSecurityInfo queries the security information for a given handle and returns the self-relative security
  1376  // descriptor result on the Go heap.
  1377  func GetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
  1378  	var winHeapSD *SECURITY_DESCRIPTOR
  1379  	err = getSecurityInfo(handle, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
  1380  	if err != nil {
  1381  		return
  1382  	}
  1383  	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
  1384  	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
  1385  }
  1386  
  1387  // GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security
  1388  // descriptor result on the Go heap.
  1389  func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
  1390  	var winHeapSD *SECURITY_DESCRIPTOR
  1391  	err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
  1392  	if err != nil {
  1393  		return
  1394  	}
  1395  	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
  1396  	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
  1397  }
  1398  
  1399  // BuildSecurityDescriptor makes a new security descriptor using the input trustees, explicit access lists, and
  1400  // prior security descriptor to be merged, any of which can be nil, returning the self-relative security descriptor
  1401  // result on the Go heap.
  1402  func BuildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, accessEntries []EXPLICIT_ACCESS, auditEntries []EXPLICIT_ACCESS, mergedSecurityDescriptor *SECURITY_DESCRIPTOR) (sd *SECURITY_DESCRIPTOR, err error) {
  1403  	var winHeapSD *SECURITY_DESCRIPTOR
  1404  	var winHeapSDSize uint32
  1405  	var firstAccessEntry *EXPLICIT_ACCESS
  1406  	if len(accessEntries) > 0 {
  1407  		firstAccessEntry = &accessEntries[0]
  1408  	}
  1409  	var firstAuditEntry *EXPLICIT_ACCESS
  1410  	if len(auditEntries) > 0 {
  1411  		firstAuditEntry = &auditEntries[0]
  1412  	}
  1413  	err = buildSecurityDescriptor(owner, group, uint32(len(accessEntries)), firstAccessEntry, uint32(len(auditEntries)), firstAuditEntry, mergedSecurityDescriptor, &winHeapSDSize, &winHeapSD)
  1414  	if err != nil {
  1415  		return
  1416  	}
  1417  	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
  1418  	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
  1419  }
  1420  
  1421  // NewSecurityDescriptor creates and initializes a new absolute security descriptor.
  1422  func NewSecurityDescriptor() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
  1423  	absoluteSD = &SECURITY_DESCRIPTOR{}
  1424  	err = initializeSecurityDescriptor(absoluteSD, 1)
  1425  	return
  1426  }
  1427  
  1428  // ACLFromEntries returns a new ACL on the Go heap containing a list of explicit entries as well as those of another ACL.
  1429  // Both explicitEntries and mergedACL are optional and can be nil.
  1430  func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL, err error) {
  1431  	var firstExplicitEntry *EXPLICIT_ACCESS
  1432  	if len(explicitEntries) > 0 {
  1433  		firstExplicitEntry = &explicitEntries[0]
  1434  	}
  1435  	var winHeapACL *ACL
  1436  	err = setEntriesInAcl(uint32(len(explicitEntries)), firstExplicitEntry, mergedACL, &winHeapACL)
  1437  	if err != nil {
  1438  		return
  1439  	}
  1440  	defer LocalFree(Handle(unsafe.Pointer(winHeapACL)))
  1441  	aclBytes := make([]byte, winHeapACL.aclSize)
  1442  	copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)])
  1443  	return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil
  1444  }
  1445  

View as plain text