cubefs

Форк
0
/x
/
security_windows.go 
1444 строки · 52.2 Кб
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.