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