go-tg-screenshot-bot

Форк
0
1458 строк · 53.1 Кб
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 = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, absoluteSDSize)[0]))
1307
	}
1308
	var (
1309
		dacl  *ACL
1310
		sacl  *ACL
1311
		owner *SID
1312
		group *SID
1313
	)
1314
	if daclSize > 0 {
1315
		dacl = (*ACL)(unsafe.Pointer(&make([]byte, daclSize)[0]))
1316
	}
1317
	if saclSize > 0 {
1318
		sacl = (*ACL)(unsafe.Pointer(&make([]byte, saclSize)[0]))
1319
	}
1320
	if ownerSize > 0 {
1321
		owner = (*SID)(unsafe.Pointer(&make([]byte, ownerSize)[0]))
1322
	}
1323
	if groupSize > 0 {
1324
		group = (*SID)(unsafe.Pointer(&make([]byte, groupSize)[0]))
1325
	}
1326
	err = makeAbsoluteSD(selfRelativeSD, absoluteSD, &absoluteSDSize,
1327
		dacl, &daclSize, sacl, &saclSize, owner, &ownerSize, group, &groupSize)
1328
	return
1329
}
1330

1331
// ToSelfRelative converts an absolute security descriptor into a self-relative one.
1332
func (absoluteSD *SECURITY_DESCRIPTOR) ToSelfRelative() (selfRelativeSD *SECURITY_DESCRIPTOR, err error) {
1333
	control, _, err := absoluteSD.Control()
1334
	if err != nil {
1335
		return
1336
	}
1337
	if control&SE_SELF_RELATIVE != 0 {
1338
		err = ERROR_INVALID_PARAMETER
1339
		return
1340
	}
1341
	var selfRelativeSDSize uint32
1342
	err = makeSelfRelativeSD(absoluteSD, nil, &selfRelativeSDSize)
1343
	switch err {
1344
	case ERROR_INSUFFICIENT_BUFFER:
1345
	case nil:
1346
		// makeSelfRelativeSD is expected to fail, but it succeeds.
1347
		return nil, ERROR_INTERNAL_ERROR
1348
	default:
1349
		return nil, err
1350
	}
1351
	if selfRelativeSDSize > 0 {
1352
		selfRelativeSD = (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&make([]byte, selfRelativeSDSize)[0]))
1353
	}
1354
	err = makeSelfRelativeSD(absoluteSD, selfRelativeSD, &selfRelativeSDSize)
1355
	return
1356
}
1357

1358
func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() *SECURITY_DESCRIPTOR {
1359
	sdLen := int(selfRelativeSD.Length())
1360
	const min = int(unsafe.Sizeof(SECURITY_DESCRIPTOR{}))
1361
	if sdLen < min {
1362
		sdLen = min
1363
	}
1364

1365
	src := unsafe.Slice((*byte)(unsafe.Pointer(selfRelativeSD)), sdLen)
1366
	// SECURITY_DESCRIPTOR has pointers in it, which means checkptr expects for it to
1367
	// be aligned properly. When we're copying a Windows-allocated struct to a
1368
	// Go-allocated one, make sure that the Go allocation is aligned to the
1369
	// pointer size.
1370
	const psize = int(unsafe.Sizeof(uintptr(0)))
1371
	alloc := make([]uintptr, (sdLen+psize-1)/psize)
1372
	dst := unsafe.Slice((*byte)(unsafe.Pointer(&alloc[0])), sdLen)
1373
	copy(dst, src)
1374
	return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0]))
1375
}
1376

1377
// SecurityDescriptorFromString converts an SDDL string describing a security descriptor into a
1378
// self-relative security descriptor object allocated on the Go heap.
1379
func SecurityDescriptorFromString(sddl string) (sd *SECURITY_DESCRIPTOR, err error) {
1380
	var winHeapSD *SECURITY_DESCRIPTOR
1381
	err = convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &winHeapSD, nil)
1382
	if err != nil {
1383
		return
1384
	}
1385
	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
1386
	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
1387
}
1388

1389
// GetSecurityInfo queries the security information for a given handle and returns the self-relative security
1390
// descriptor result on the Go heap.
1391
func GetSecurityInfo(handle Handle, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
1392
	var winHeapSD *SECURITY_DESCRIPTOR
1393
	err = getSecurityInfo(handle, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
1394
	if err != nil {
1395
		return
1396
	}
1397
	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
1398
	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
1399
}
1400

1401
// GetNamedSecurityInfo queries the security information for a given named object and returns the self-relative security
1402
// descriptor result on the Go heap.
1403
func GetNamedSecurityInfo(objectName string, objectType SE_OBJECT_TYPE, securityInformation SECURITY_INFORMATION) (sd *SECURITY_DESCRIPTOR, err error) {
1404
	var winHeapSD *SECURITY_DESCRIPTOR
1405
	err = getNamedSecurityInfo(objectName, objectType, securityInformation, nil, nil, nil, nil, &winHeapSD)
1406
	if err != nil {
1407
		return
1408
	}
1409
	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
1410
	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
1411
}
1412

1413
// BuildSecurityDescriptor makes a new security descriptor using the input trustees, explicit access lists, and
1414
// prior security descriptor to be merged, any of which can be nil, returning the self-relative security descriptor
1415
// result on the Go heap.
1416
func BuildSecurityDescriptor(owner *TRUSTEE, group *TRUSTEE, accessEntries []EXPLICIT_ACCESS, auditEntries []EXPLICIT_ACCESS, mergedSecurityDescriptor *SECURITY_DESCRIPTOR) (sd *SECURITY_DESCRIPTOR, err error) {
1417
	var winHeapSD *SECURITY_DESCRIPTOR
1418
	var winHeapSDSize uint32
1419
	var firstAccessEntry *EXPLICIT_ACCESS
1420
	if len(accessEntries) > 0 {
1421
		firstAccessEntry = &accessEntries[0]
1422
	}
1423
	var firstAuditEntry *EXPLICIT_ACCESS
1424
	if len(auditEntries) > 0 {
1425
		firstAuditEntry = &auditEntries[0]
1426
	}
1427
	err = buildSecurityDescriptor(owner, group, uint32(len(accessEntries)), firstAccessEntry, uint32(len(auditEntries)), firstAuditEntry, mergedSecurityDescriptor, &winHeapSDSize, &winHeapSD)
1428
	if err != nil {
1429
		return
1430
	}
1431
	defer LocalFree(Handle(unsafe.Pointer(winHeapSD)))
1432
	return winHeapSD.copySelfRelativeSecurityDescriptor(), nil
1433
}
1434

1435
// NewSecurityDescriptor creates and initializes a new absolute security descriptor.
1436
func NewSecurityDescriptor() (absoluteSD *SECURITY_DESCRIPTOR, err error) {
1437
	absoluteSD = &SECURITY_DESCRIPTOR{}
1438
	err = initializeSecurityDescriptor(absoluteSD, 1)
1439
	return
1440
}
1441

1442
// ACLFromEntries returns a new ACL on the Go heap containing a list of explicit entries as well as those of another ACL.
1443
// Both explicitEntries and mergedACL are optional and can be nil.
1444
func ACLFromEntries(explicitEntries []EXPLICIT_ACCESS, mergedACL *ACL) (acl *ACL, err error) {
1445
	var firstExplicitEntry *EXPLICIT_ACCESS
1446
	if len(explicitEntries) > 0 {
1447
		firstExplicitEntry = &explicitEntries[0]
1448
	}
1449
	var winHeapACL *ACL
1450
	err = setEntriesInAcl(uint32(len(explicitEntries)), firstExplicitEntry, mergedACL, &winHeapACL)
1451
	if err != nil {
1452
		return
1453
	}
1454
	defer LocalFree(Handle(unsafe.Pointer(winHeapACL)))
1455
	aclBytes := make([]byte, winHeapACL.aclSize)
1456
	copy(aclBytes, (*[(1 << 31) - 1]byte)(unsafe.Pointer(winHeapACL))[:len(aclBytes):len(aclBytes)])
1457
	return (*ACL)(unsafe.Pointer(&aclBytes[0])), nil
1458
}
1459

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

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

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

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