Import of https://github.com/ciena/voltctl at commit 40d61fbf3f910ed4017cf67c9c79e8e1f82a33a5

Change-Id: I8464c59e60d76cb8612891db3303878975b5416c
diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go
new file mode 100644
index 0000000..b84840f
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/security_windows.go
@@ -0,0 +1,844 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package windows
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+const (
+	STANDARD_RIGHTS_REQUIRED = 0xf0000
+	STANDARD_RIGHTS_READ     = 0x20000
+	STANDARD_RIGHTS_WRITE    = 0x20000
+	STANDARD_RIGHTS_EXECUTE  = 0x20000
+	STANDARD_RIGHTS_ALL      = 0x1F0000
+)
+
+const (
+	NameUnknown          = 0
+	NameFullyQualifiedDN = 1
+	NameSamCompatible    = 2
+	NameDisplay          = 3
+	NameUniqueId         = 6
+	NameCanonical        = 7
+	NameUserPrincipal    = 8
+	NameCanonicalEx      = 9
+	NameServicePrincipal = 10
+	NameDnsDomain        = 12
+)
+
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
+// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
+//sys	TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
+//sys	GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
+
+// TranslateAccountName converts a directory service
+// object name from one format to another.
+func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
+	u, e := UTF16PtrFromString(username)
+	if e != nil {
+		return "", e
+	}
+	n := uint32(50)
+	for {
+		b := make([]uint16, n)
+		e = TranslateName(u, from, to, &b[0], &n)
+		if e == nil {
+			return UTF16ToString(b[:n]), nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return "", e
+		}
+		if n <= uint32(len(b)) {
+			return "", e
+		}
+	}
+}
+
+const (
+	// do not reorder
+	NetSetupUnknownStatus = iota
+	NetSetupUnjoined
+	NetSetupWorkgroupName
+	NetSetupDomainName
+)
+
+type UserInfo10 struct {
+	Name       *uint16
+	Comment    *uint16
+	UsrComment *uint16
+	FullName   *uint16
+}
+
+//sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
+//sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
+//sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
+
+const (
+	// do not reorder
+	SidTypeUser = 1 + iota
+	SidTypeGroup
+	SidTypeDomain
+	SidTypeAlias
+	SidTypeWellKnownGroup
+	SidTypeDeletedAccount
+	SidTypeInvalid
+	SidTypeUnknown
+	SidTypeComputer
+	SidTypeLabel
+)
+
+type SidIdentifierAuthority struct {
+	Value [6]byte
+}
+
+var (
+	SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
+	SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
+	SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
+	SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
+	SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
+	SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
+	SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
+)
+
+const (
+	SECURITY_NULL_RID                   = 0
+	SECURITY_WORLD_RID                  = 0
+	SECURITY_LOCAL_RID                  = 0
+	SECURITY_CREATOR_OWNER_RID          = 0
+	SECURITY_CREATOR_GROUP_RID          = 1
+	SECURITY_DIALUP_RID                 = 1
+	SECURITY_NETWORK_RID                = 2
+	SECURITY_BATCH_RID                  = 3
+	SECURITY_INTERACTIVE_RID            = 4
+	SECURITY_LOGON_IDS_RID              = 5
+	SECURITY_SERVICE_RID                = 6
+	SECURITY_LOCAL_SYSTEM_RID           = 18
+	SECURITY_BUILTIN_DOMAIN_RID         = 32
+	SECURITY_PRINCIPAL_SELF_RID         = 10
+	SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
+	SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
+	SECURITY_LOGON_IDS_RID_COUNT        = 0x3
+	SECURITY_ANONYMOUS_LOGON_RID        = 0x7
+	SECURITY_PROXY_RID                  = 0x8
+	SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
+	SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
+	SECURITY_AUTHENTICATED_USER_RID     = 0xb
+	SECURITY_RESTRICTED_CODE_RID        = 0xc
+	SECURITY_NT_NON_UNIQUE_RID          = 0x15
+)
+
+// Predefined domain-relative RIDs for local groups.
+// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx
+const (
+	DOMAIN_ALIAS_RID_ADMINS                         = 0x220
+	DOMAIN_ALIAS_RID_USERS                          = 0x221
+	DOMAIN_ALIAS_RID_GUESTS                         = 0x222
+	DOMAIN_ALIAS_RID_POWER_USERS                    = 0x223
+	DOMAIN_ALIAS_RID_ACCOUNT_OPS                    = 0x224
+	DOMAIN_ALIAS_RID_SYSTEM_OPS                     = 0x225
+	DOMAIN_ALIAS_RID_PRINT_OPS                      = 0x226
+	DOMAIN_ALIAS_RID_BACKUP_OPS                     = 0x227
+	DOMAIN_ALIAS_RID_REPLICATOR                     = 0x228
+	DOMAIN_ALIAS_RID_RAS_SERVERS                    = 0x229
+	DOMAIN_ALIAS_RID_PREW2KCOMPACCESS               = 0x22a
+	DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS           = 0x22b
+	DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS      = 0x22c
+	DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d
+	DOMAIN_ALIAS_RID_MONITORING_USERS               = 0x22e
+	DOMAIN_ALIAS_RID_LOGGING_USERS                  = 0x22f
+	DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS            = 0x230
+	DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS             = 0x231
+	DOMAIN_ALIAS_RID_DCOM_USERS                     = 0x232
+	DOMAIN_ALIAS_RID_IUSERS                         = 0x238
+	DOMAIN_ALIAS_RID_CRYPTO_OPERATORS               = 0x239
+	DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP     = 0x23b
+	DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c
+	DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP        = 0x23d
+	DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP      = 0x23e
+)
+
+//sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
+//sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
+//sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
+//sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
+//sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
+//sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
+//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
+//sys	createWellKnownSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID, sid *SID, sizeSid *uint32) (err error) = advapi32.CreateWellKnownSid
+//sys	isWellKnownSid(sid *SID, sidType WELL_KNOWN_SID_TYPE) (isWellKnown bool) = advapi32.IsWellKnownSid
+//sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
+//sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
+//sys	getSidIdentifierAuthority(sid *SID) (authority *SidIdentifierAuthority) = advapi32.GetSidIdentifierAuthority
+//sys	getSidSubAuthorityCount(sid *SID) (count *uint8) = advapi32.GetSidSubAuthorityCount
+//sys	getSidSubAuthority(sid *SID, index uint32) (subAuthority *uint32) = advapi32.GetSidSubAuthority
+//sys	isValidSid(sid *SID) (isValid bool) = advapi32.IsValidSid
+
+// The security identifier (SID) structure is a variable-length
+// structure used to uniquely identify users or groups.
+type SID struct{}
+
+// StringToSid converts a string-format security identifier
+// SID into a valid, functional SID.
+func StringToSid(s string) (*SID, error) {
+	var sid *SID
+	p, e := UTF16PtrFromString(s)
+	if e != nil {
+		return nil, e
+	}
+	e = ConvertStringSidToSid(p, &sid)
+	if e != nil {
+		return nil, e
+	}
+	defer LocalFree((Handle)(unsafe.Pointer(sid)))
+	return sid.Copy()
+}
+
+// LookupSID retrieves a security identifier SID for the account
+// and the name of the domain on which the account was found.
+// System specify target computer to search.
+func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
+	if len(account) == 0 {
+		return nil, "", 0, syscall.EINVAL
+	}
+	acc, e := UTF16PtrFromString(account)
+	if e != nil {
+		return nil, "", 0, e
+	}
+	var sys *uint16
+	if len(system) > 0 {
+		sys, e = UTF16PtrFromString(system)
+		if e != nil {
+			return nil, "", 0, e
+		}
+	}
+	n := uint32(50)
+	dn := uint32(50)
+	for {
+		b := make([]byte, n)
+		db := make([]uint16, dn)
+		sid = (*SID)(unsafe.Pointer(&b[0]))
+		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
+		if e == nil {
+			return sid, UTF16ToString(db), accType, nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return nil, "", 0, e
+		}
+		if n <= uint32(len(b)) {
+			return nil, "", 0, e
+		}
+	}
+}
+
+// String converts SID to a string format
+// suitable for display, storage, or transmission.
+func (sid *SID) String() (string, error) {
+	var s *uint16
+	e := ConvertSidToStringSid(sid, &s)
+	if e != nil {
+		return "", e
+	}
+	defer LocalFree((Handle)(unsafe.Pointer(s)))
+	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
+}
+
+// Len returns the length, in bytes, of a valid security identifier SID.
+func (sid *SID) Len() int {
+	return int(GetLengthSid(sid))
+}
+
+// Copy creates a duplicate of security identifier SID.
+func (sid *SID) Copy() (*SID, error) {
+	b := make([]byte, sid.Len())
+	sid2 := (*SID)(unsafe.Pointer(&b[0]))
+	e := CopySid(uint32(len(b)), sid2, sid)
+	if e != nil {
+		return nil, e
+	}
+	return sid2, nil
+}
+
+// IdentifierAuthority returns the identifier authority of the SID.
+func (sid *SID) IdentifierAuthority() SidIdentifierAuthority {
+	return *getSidIdentifierAuthority(sid)
+}
+
+// SubAuthorityCount returns the number of sub-authorities in the SID.
+func (sid *SID) SubAuthorityCount() uint8 {
+	return *getSidSubAuthorityCount(sid)
+}
+
+// SubAuthority returns the sub-authority of the SID as specified by
+// the index, which must be less than sid.SubAuthorityCount().
+func (sid *SID) SubAuthority(idx uint32) uint32 {
+	if idx >= uint32(sid.SubAuthorityCount()) {
+		panic("sub-authority index out of range")
+	}
+	return *getSidSubAuthority(sid, idx)
+}
+
+// IsValid returns whether the SID has a valid revision and length.
+func (sid *SID) IsValid() bool {
+	return isValidSid(sid)
+}
+
+// Equals compares two SIDs for equality.
+func (sid *SID) Equals(sid2 *SID) bool {
+	return EqualSid(sid, sid2)
+}
+
+// IsWellKnown determines whether the SID matches the well-known sidType.
+func (sid *SID) IsWellKnown(sidType WELL_KNOWN_SID_TYPE) bool {
+	return isWellKnownSid(sid, sidType)
+}
+
+// LookupAccount retrieves the name of the account for this SID
+// and the name of the first domain on which this SID is found.
+// System specify target computer to search for.
+func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
+	var sys *uint16
+	if len(system) > 0 {
+		sys, err = UTF16PtrFromString(system)
+		if err != nil {
+			return "", "", 0, err
+		}
+	}
+	n := uint32(50)
+	dn := uint32(50)
+	for {
+		b := make([]uint16, n)
+		db := make([]uint16, dn)
+		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
+		if e == nil {
+			return UTF16ToString(b), UTF16ToString(db), accType, nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return "", "", 0, e
+		}
+		if n <= uint32(len(b)) {
+			return "", "", 0, e
+		}
+	}
+}
+
+// Various types of pre-specified SIDs that can be synthesized and compared at runtime.
+type WELL_KNOWN_SID_TYPE uint32
+
+const (
+	WinNullSid                                    = 0
+	WinWorldSid                                   = 1
+	WinLocalSid                                   = 2
+	WinCreatorOwnerSid                            = 3
+	WinCreatorGroupSid                            = 4
+	WinCreatorOwnerServerSid                      = 5
+	WinCreatorGroupServerSid                      = 6
+	WinNtAuthoritySid                             = 7
+	WinDialupSid                                  = 8
+	WinNetworkSid                                 = 9
+	WinBatchSid                                   = 10
+	WinInteractiveSid                             = 11
+	WinServiceSid                                 = 12
+	WinAnonymousSid                               = 13
+	WinProxySid                                   = 14
+	WinEnterpriseControllersSid                   = 15
+	WinSelfSid                                    = 16
+	WinAuthenticatedUserSid                       = 17
+	WinRestrictedCodeSid                          = 18
+	WinTerminalServerSid                          = 19
+	WinRemoteLogonIdSid                           = 20
+	WinLogonIdsSid                                = 21
+	WinLocalSystemSid                             = 22
+	WinLocalServiceSid                            = 23
+	WinNetworkServiceSid                          = 24
+	WinBuiltinDomainSid                           = 25
+	WinBuiltinAdministratorsSid                   = 26
+	WinBuiltinUsersSid                            = 27
+	WinBuiltinGuestsSid                           = 28
+	WinBuiltinPowerUsersSid                       = 29
+	WinBuiltinAccountOperatorsSid                 = 30
+	WinBuiltinSystemOperatorsSid                  = 31
+	WinBuiltinPrintOperatorsSid                   = 32
+	WinBuiltinBackupOperatorsSid                  = 33
+	WinBuiltinReplicatorSid                       = 34
+	WinBuiltinPreWindows2000CompatibleAccessSid   = 35
+	WinBuiltinRemoteDesktopUsersSid               = 36
+	WinBuiltinNetworkConfigurationOperatorsSid    = 37
+	WinAccountAdministratorSid                    = 38
+	WinAccountGuestSid                            = 39
+	WinAccountKrbtgtSid                           = 40
+	WinAccountDomainAdminsSid                     = 41
+	WinAccountDomainUsersSid                      = 42
+	WinAccountDomainGuestsSid                     = 43
+	WinAccountComputersSid                        = 44
+	WinAccountControllersSid                      = 45
+	WinAccountCertAdminsSid                       = 46
+	WinAccountSchemaAdminsSid                     = 47
+	WinAccountEnterpriseAdminsSid                 = 48
+	WinAccountPolicyAdminsSid                     = 49
+	WinAccountRasAndIasServersSid                 = 50
+	WinNTLMAuthenticationSid                      = 51
+	WinDigestAuthenticationSid                    = 52
+	WinSChannelAuthenticationSid                  = 53
+	WinThisOrganizationSid                        = 54
+	WinOtherOrganizationSid                       = 55
+	WinBuiltinIncomingForestTrustBuildersSid      = 56
+	WinBuiltinPerfMonitoringUsersSid              = 57
+	WinBuiltinPerfLoggingUsersSid                 = 58
+	WinBuiltinAuthorizationAccessSid              = 59
+	WinBuiltinTerminalServerLicenseServersSid     = 60
+	WinBuiltinDCOMUsersSid                        = 61
+	WinBuiltinIUsersSid                           = 62
+	WinIUserSid                                   = 63
+	WinBuiltinCryptoOperatorsSid                  = 64
+	WinUntrustedLabelSid                          = 65
+	WinLowLabelSid                                = 66
+	WinMediumLabelSid                             = 67
+	WinHighLabelSid                               = 68
+	WinSystemLabelSid                             = 69
+	WinWriteRestrictedCodeSid                     = 70
+	WinCreatorOwnerRightsSid                      = 71
+	WinCacheablePrincipalsGroupSid                = 72
+	WinNonCacheablePrincipalsGroupSid             = 73
+	WinEnterpriseReadonlyControllersSid           = 74
+	WinAccountReadonlyControllersSid              = 75
+	WinBuiltinEventLogReadersGroup                = 76
+	WinNewEnterpriseReadonlyControllersSid        = 77
+	WinBuiltinCertSvcDComAccessGroup              = 78
+	WinMediumPlusLabelSid                         = 79
+	WinLocalLogonSid                              = 80
+	WinConsoleLogonSid                            = 81
+	WinThisOrganizationCertificateSid             = 82
+	WinApplicationPackageAuthoritySid             = 83
+	WinBuiltinAnyPackageSid                       = 84
+	WinCapabilityInternetClientSid                = 85
+	WinCapabilityInternetClientServerSid          = 86
+	WinCapabilityPrivateNetworkClientServerSid    = 87
+	WinCapabilityPicturesLibrarySid               = 88
+	WinCapabilityVideosLibrarySid                 = 89
+	WinCapabilityMusicLibrarySid                  = 90
+	WinCapabilityDocumentsLibrarySid              = 91
+	WinCapabilitySharedUserCertificatesSid        = 92
+	WinCapabilityEnterpriseAuthenticationSid      = 93
+	WinCapabilityRemovableStorageSid              = 94
+	WinBuiltinRDSRemoteAccessServersSid           = 95
+	WinBuiltinRDSEndpointServersSid               = 96
+	WinBuiltinRDSManagementServersSid             = 97
+	WinUserModeDriversSid                         = 98
+	WinBuiltinHyperVAdminsSid                     = 99
+	WinAccountCloneableControllersSid             = 100
+	WinBuiltinAccessControlAssistanceOperatorsSid = 101
+	WinBuiltinRemoteManagementUsersSid            = 102
+	WinAuthenticationAuthorityAssertedSid         = 103
+	WinAuthenticationServiceAssertedSid           = 104
+	WinLocalAccountSid                            = 105
+	WinLocalAccountAndAdministratorSid            = 106
+	WinAccountProtectedUsersSid                   = 107
+	WinCapabilityAppointmentsSid                  = 108
+	WinCapabilityContactsSid                      = 109
+	WinAccountDefaultSystemManagedSid             = 110
+	WinBuiltinDefaultSystemManagedGroupSid        = 111
+	WinBuiltinStorageReplicaAdminsSid             = 112
+	WinAccountKeyAdminsSid                        = 113
+	WinAccountEnterpriseKeyAdminsSid              = 114
+	WinAuthenticationKeyTrustSid                  = 115
+	WinAuthenticationKeyPropertyMFASid            = 116
+	WinAuthenticationKeyPropertyAttestationSid    = 117
+	WinAuthenticationFreshKeyAuthSid              = 118
+	WinBuiltinDeviceOwnersSid                     = 119
+)
+
+// Creates a SID for a well-known predefined alias, generally using the constants of the form
+// Win*Sid, for the local machine.
+func CreateWellKnownSid(sidType WELL_KNOWN_SID_TYPE) (*SID, error) {
+	return CreateWellKnownDomainSid(sidType, nil)
+}
+
+// Creates a SID for a well-known predefined alias, generally using the constants of the form
+// Win*Sid, for the domain specified by the domainSid parameter.
+func CreateWellKnownDomainSid(sidType WELL_KNOWN_SID_TYPE, domainSid *SID) (*SID, error) {
+	n := uint32(50)
+	for {
+		b := make([]byte, n)
+		sid := (*SID)(unsafe.Pointer(&b[0]))
+		err := createWellKnownSid(sidType, domainSid, sid, &n)
+		if err == nil {
+			return sid, nil
+		}
+		if err != ERROR_INSUFFICIENT_BUFFER {
+			return nil, err
+		}
+		if n <= uint32(len(b)) {
+			return nil, err
+		}
+	}
+}
+
+const (
+	// do not reorder
+	TOKEN_ASSIGN_PRIMARY = 1 << iota
+	TOKEN_DUPLICATE
+	TOKEN_IMPERSONATE
+	TOKEN_QUERY
+	TOKEN_QUERY_SOURCE
+	TOKEN_ADJUST_PRIVILEGES
+	TOKEN_ADJUST_GROUPS
+	TOKEN_ADJUST_DEFAULT
+	TOKEN_ADJUST_SESSIONID
+
+	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
+		TOKEN_ASSIGN_PRIMARY |
+		TOKEN_DUPLICATE |
+		TOKEN_IMPERSONATE |
+		TOKEN_QUERY |
+		TOKEN_QUERY_SOURCE |
+		TOKEN_ADJUST_PRIVILEGES |
+		TOKEN_ADJUST_GROUPS |
+		TOKEN_ADJUST_DEFAULT |
+		TOKEN_ADJUST_SESSIONID
+	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
+	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
+		TOKEN_ADJUST_PRIVILEGES |
+		TOKEN_ADJUST_GROUPS |
+		TOKEN_ADJUST_DEFAULT
+	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
+)
+
+const (
+	// do not reorder
+	TokenUser = 1 + iota
+	TokenGroups
+	TokenPrivileges
+	TokenOwner
+	TokenPrimaryGroup
+	TokenDefaultDacl
+	TokenSource
+	TokenType
+	TokenImpersonationLevel
+	TokenStatistics
+	TokenRestrictedSids
+	TokenSessionId
+	TokenGroupsAndPrivileges
+	TokenSessionReference
+	TokenSandBoxInert
+	TokenAuditPolicy
+	TokenOrigin
+	TokenElevationType
+	TokenLinkedToken
+	TokenElevation
+	TokenHasRestrictions
+	TokenAccessInformation
+	TokenVirtualizationAllowed
+	TokenVirtualizationEnabled
+	TokenIntegrityLevel
+	TokenUIAccess
+	TokenMandatoryPolicy
+	TokenLogonSid
+	MaxTokenInfoClass
+)
+
+// Group attributes inside of Tokengroups.Groups[i].Attributes
+const (
+	SE_GROUP_MANDATORY          = 0x00000001
+	SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002
+	SE_GROUP_ENABLED            = 0x00000004
+	SE_GROUP_OWNER              = 0x00000008
+	SE_GROUP_USE_FOR_DENY_ONLY  = 0x00000010
+	SE_GROUP_INTEGRITY          = 0x00000020
+	SE_GROUP_INTEGRITY_ENABLED  = 0x00000040
+	SE_GROUP_LOGON_ID           = 0xC0000000
+	SE_GROUP_RESOURCE           = 0x20000000
+	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
+)
+
+// Privilege attributes
+const (
+	SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001
+	SE_PRIVILEGE_ENABLED            = 0x00000002
+	SE_PRIVILEGE_REMOVED            = 0x00000004
+	SE_PRIVILEGE_USED_FOR_ACCESS    = 0x80000000
+	SE_PRIVILEGE_VALID_ATTRIBUTES   = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_REMOVED | SE_PRIVILEGE_USED_FOR_ACCESS
+)
+
+// Token types
+const (
+	TokenPrimary       = 1
+	TokenImpersonation = 2
+)
+
+// Impersonation levels
+const (
+	SecurityAnonymous      = 0
+	SecurityIdentification = 1
+	SecurityImpersonation  = 2
+	SecurityDelegation     = 3
+)
+
+type LUID struct {
+	LowPart  uint32
+	HighPart int32
+}
+
+type LUIDAndAttributes struct {
+	Luid       LUID
+	Attributes uint32
+}
+
+type SIDAndAttributes struct {
+	Sid        *SID
+	Attributes uint32
+}
+
+type Tokenuser struct {
+	User SIDAndAttributes
+}
+
+type Tokenprimarygroup struct {
+	PrimaryGroup *SID
+}
+
+type Tokengroups struct {
+	GroupCount uint32
+	Groups     [1]SIDAndAttributes
+}
+
+type Tokenprivileges struct {
+	PrivilegeCount uint32
+	Privileges     [1]LUIDAndAttributes
+}
+
+type Tokenmandatorylabel struct {
+	Label SIDAndAttributes
+}
+
+func (tml *Tokenmandatorylabel) Size() uint32 {
+	return uint32(unsafe.Sizeof(Tokenmandatorylabel{})) + GetLengthSid(tml.Label.Sid)
+}
+
+// Authorization Functions
+//sys	checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership
+//sys	OpenProcessToken(process Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
+//sys	OpenThreadToken(thread Handle, access uint32, openAsSelf bool, token *Token) (err error) = advapi32.OpenThreadToken
+//sys	ImpersonateSelf(impersonationlevel uint32) (err error) = advapi32.ImpersonateSelf
+//sys	RevertToSelf() (err error) = advapi32.RevertToSelf
+//sys	SetThreadToken(thread *Handle, token Token) (err error) = advapi32.SetThreadToken
+//sys	LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) = advapi32.LookupPrivilegeValueW
+//sys	AdjustTokenPrivileges(token Token, disableAllPrivileges bool, newstate *Tokenprivileges, buflen uint32, prevstate *Tokenprivileges, returnlen *uint32) (err error) = advapi32.AdjustTokenPrivileges
+//sys	AdjustTokenGroups(token Token, resetToDefault bool, newstate *Tokengroups, buflen uint32, prevstate *Tokengroups, returnlen *uint32) (err error) = advapi32.AdjustTokenGroups
+//sys	GetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
+//sys	SetTokenInformation(token Token, infoClass uint32, info *byte, infoLen uint32) (err error) = advapi32.SetTokenInformation
+//sys	DuplicateTokenEx(existingToken Token, desiredAccess uint32, tokenAttributes *SecurityAttributes, impersonationLevel uint32, tokenType uint32, newToken *Token) (err error) = advapi32.DuplicateTokenEx
+//sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
+//sys	getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
+
+// An access token contains the security information for a logon session.
+// The system creates an access token when a user logs on, and every
+// process executed on behalf of the user has a copy of the token.
+// The token identifies the user, the user's groups, and the user's
+// privileges. The system uses the token to control access to securable
+// objects and to control the ability of the user to perform various
+// system-related operations on the local computer.
+type Token Handle
+
+// OpenCurrentProcessToken opens the access token
+// associated with current process. It is a real
+// token that needs to be closed, unlike
+// GetCurrentProcessToken.
+func OpenCurrentProcessToken() (Token, error) {
+	p, e := GetCurrentProcess()
+	if e != nil {
+		return 0, e
+	}
+	var t Token
+	e = OpenProcessToken(p, TOKEN_QUERY, &t)
+	if e != nil {
+		return 0, e
+	}
+	return t, nil
+}
+
+// GetCurrentProcessToken returns the access token associated with
+// the current process. It is a pseudo token that does not need
+// to be closed.
+func GetCurrentProcessToken() Token {
+	return Token(^uintptr(4 - 1))
+}
+
+// GetCurrentThreadToken return the access token associated with
+// the current thread. It is a pseudo token that does not need
+// to be closed.
+func GetCurrentThreadToken() Token {
+	return Token(^uintptr(5 - 1))
+}
+
+// GetCurrentThreadEffectiveToken returns the effective access token
+// associated with the current thread. It is a pseudo token that does
+// not need to be closed.
+func GetCurrentThreadEffectiveToken() Token {
+	return Token(^uintptr(6 - 1))
+}
+
+// Close releases access to access token.
+func (t Token) Close() error {
+	return CloseHandle(Handle(t))
+}
+
+// getInfo retrieves a specified type of information about an access token.
+func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
+	n := uint32(initSize)
+	for {
+		b := make([]byte, n)
+		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
+		if e == nil {
+			return unsafe.Pointer(&b[0]), nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return nil, e
+		}
+		if n <= uint32(len(b)) {
+			return nil, e
+		}
+	}
+}
+
+// GetTokenUser retrieves access token t user account information.
+func (t Token) GetTokenUser() (*Tokenuser, error) {
+	i, e := t.getInfo(TokenUser, 50)
+	if e != nil {
+		return nil, e
+	}
+	return (*Tokenuser)(i), nil
+}
+
+// GetTokenGroups retrieves group accounts associated with access token t.
+func (t Token) GetTokenGroups() (*Tokengroups, error) {
+	i, e := t.getInfo(TokenGroups, 50)
+	if e != nil {
+		return nil, e
+	}
+	return (*Tokengroups)(i), nil
+}
+
+// GetTokenPrimaryGroup retrieves access token t primary group information.
+// A pointer to a SID structure representing a group that will become
+// the primary group of any objects created by a process using this access token.
+func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
+	i, e := t.getInfo(TokenPrimaryGroup, 50)
+	if e != nil {
+		return nil, e
+	}
+	return (*Tokenprimarygroup)(i), nil
+}
+
+// GetUserProfileDirectory retrieves path to the
+// root directory of the access token t user's profile.
+func (t Token) GetUserProfileDirectory() (string, error) {
+	n := uint32(100)
+	for {
+		b := make([]uint16, n)
+		e := GetUserProfileDirectory(t, &b[0], &n)
+		if e == nil {
+			return UTF16ToString(b), nil
+		}
+		if e != ERROR_INSUFFICIENT_BUFFER {
+			return "", e
+		}
+		if n <= uint32(len(b)) {
+			return "", e
+		}
+	}
+}
+
+// IsElevated returns whether the current token is elevated from a UAC perspective.
+func (token Token) IsElevated() bool {
+	var isElevated uint32
+	var outLen uint32
+	err := GetTokenInformation(token, TokenElevation, (*byte)(unsafe.Pointer(&isElevated)), uint32(unsafe.Sizeof(isElevated)), &outLen)
+	if err != nil {
+		return false
+	}
+	return outLen == uint32(unsafe.Sizeof(isElevated)) && isElevated != 0
+}
+
+// GetLinkedToken returns the linked token, which may be an elevated UAC token.
+func (token Token) GetLinkedToken() (Token, error) {
+	var linkedToken Token
+	var outLen uint32
+	err := GetTokenInformation(token, TokenLinkedToken, (*byte)(unsafe.Pointer(&linkedToken)), uint32(unsafe.Sizeof(linkedToken)), &outLen)
+	if err != nil {
+		return Token(0), err
+	}
+	return linkedToken, nil
+}
+
+// GetSystemDirectory retrieves path to current location of the system
+// directory, which is typically, though not always, C:\Windows\System32.
+func GetSystemDirectory() (string, error) {
+	n := uint32(MAX_PATH)
+	for {
+		b := make([]uint16, n)
+		l, e := getSystemDirectory(&b[0], n)
+		if e != nil {
+			return "", e
+		}
+		if l <= n {
+			return UTF16ToString(b[:l]), nil
+		}
+		n = l
+	}
+}
+
+// IsMember reports whether the access token t is a member of the provided SID.
+func (t Token) IsMember(sid *SID) (bool, error) {
+	var b int32
+	if e := checkTokenMembership(t, sid, &b); e != nil {
+		return false, e
+	}
+	return b != 0, nil
+}
+
+const (
+	WTS_CONSOLE_CONNECT        = 0x1
+	WTS_CONSOLE_DISCONNECT     = 0x2
+	WTS_REMOTE_CONNECT         = 0x3
+	WTS_REMOTE_DISCONNECT      = 0x4
+	WTS_SESSION_LOGON          = 0x5
+	WTS_SESSION_LOGOFF         = 0x6
+	WTS_SESSION_LOCK           = 0x7
+	WTS_SESSION_UNLOCK         = 0x8
+	WTS_SESSION_REMOTE_CONTROL = 0x9
+	WTS_SESSION_CREATE         = 0xa
+	WTS_SESSION_TERMINATE      = 0xb
+)
+
+const (
+	WTSActive       = 0
+	WTSConnected    = 1
+	WTSConnectQuery = 2
+	WTSShadow       = 3
+	WTSDisconnected = 4
+	WTSIdle         = 5
+	WTSListen       = 6
+	WTSReset        = 7
+	WTSDown         = 8
+	WTSInit         = 9
+)
+
+type WTSSESSION_NOTIFICATION struct {
+	Size      uint32
+	SessionID uint32
+}
+
+type WTS_SESSION_INFO struct {
+	SessionID         uint32
+	WindowStationName *uint16
+	State             uint32
+}
+
+//sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken
+//sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW
+//sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory