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