| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- // 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
- }
- b := make([]uint16, 50)
- n := uint32(len(b))
- e = TranslateName(u, from, to, &b[0], &n)
- if e != nil {
- if e != ERROR_INSUFFICIENT_BUFFER {
- return "", e
- }
- // make receive buffers of requested size and try again
- b = make([]uint16, n)
- e = TranslateName(u, from, to, &b[0], &n)
- if e != nil {
- return "", e
- }
- }
- return UTF16ToString(b), nil
- }
- 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
- )
- //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
- // 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
- }
- }
- db := make([]uint16, 50)
- dn := uint32(len(db))
- b := make([]byte, 50)
- n := uint32(len(b))
- sid = (*SID)(unsafe.Pointer(&b[0]))
- e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
- if e != nil {
- if e != ERROR_INSUFFICIENT_BUFFER {
- return nil, "", 0, e
- }
- // make receive buffers of requested size and try again
- b = make([]byte, n)
- sid = (*SID)(unsafe.Pointer(&b[0]))
- db = make([]uint16, dn)
- e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
- if e != nil {
- return nil, "", 0, e
- }
- }
- return sid, UTF16ToString(db), accType, nil
- }
- // 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
- }
- // 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
- }
- }
- b := make([]uint16, 50)
- n := uint32(len(b))
- db := make([]uint16, 50)
- dn := uint32(len(db))
- e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
- if e != nil {
- if e != ERROR_INSUFFICIENT_BUFFER {
- return "", "", 0, e
- }
- // make receive buffers of requested size and try again
- b = make([]uint16, n)
- db = make([]uint16, dn)
- e = LookupAccountSid(nil, sid, &b[0], &n, &db[0], &dn, &accType)
- if e != nil {
- return "", "", 0, e
- }
- }
- return UTF16ToString(b), UTF16ToString(db), accType, nil
- }
- 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_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_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
- )
- type SIDAndAttributes struct {
- Sid *SID
- Attributes uint32
- }
- type Tokenuser struct {
- User SIDAndAttributes
- }
- type Tokenprimarygroup struct {
- PrimaryGroup *SID
- }
- //sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
- //sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
- //sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
- // 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.
- 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
- }
- // 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) {
- b := make([]byte, initSize)
- var n uint32
- e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
- if e != nil {
- if e != ERROR_INSUFFICIENT_BUFFER {
- return nil, e
- }
- // make receive buffers of requested size and try again
- b = make([]byte, n)
- e = GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
- if e != nil {
- return nil, e
- }
- }
- return unsafe.Pointer(&b[0]), nil
- }
- // 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
- }
- // 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) {
- b := make([]uint16, 100)
- n := uint32(len(b))
- e := GetUserProfileDirectory(t, &b[0], &n)
- if e != nil {
- if e != ERROR_INSUFFICIENT_BUFFER {
- return "", e
- }
- // make receive buffers of requested size and try again
- b = make([]uint16, n)
- e = GetUserProfileDirectory(t, &b[0], &n)
- if e != nil {
- return "", e
- }
- }
- return UTF16ToString(b), nil
- }
|