github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/syscall/security_windows.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package syscall
     6  
     7  import (
     8  	"unsafe"
     9  )
    10  
    11  const (
    12  	STANDARD_RIGHTS_REQUIRED = 0xf0000
    13  	STANDARD_RIGHTS_READ     = 0x20000
    14  	STANDARD_RIGHTS_WRITE    = 0x20000
    15  	STANDARD_RIGHTS_EXECUTE  = 0x20000
    16  	STANDARD_RIGHTS_ALL      = 0x1F0000
    17  )
    18  
    19  const (
    20  	NameUnknown          = 0
    21  	NameFullyQualifiedDN = 1
    22  	NameSamCompatible    = 2
    23  	NameDisplay          = 3
    24  	NameUniqueId         = 6
    25  	NameCanonical        = 7
    26  	NameUserPrincipal    = 8
    27  	NameCanonicalEx      = 9
    28  	NameServicePrincipal = 10
    29  	NameDnsDomain        = 12
    30  )
    31  
    32  // This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
    33  // http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
    34  //sys	TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
    35  //sys	GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
    36  
    37  // TranslateAccountName converts a directory service
    38  // object name from one format to another.
    39  func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
    40  	u, e := UTF16PtrFromString(username)
    41  	if e != nil {
    42  		return "", e
    43  	}
    44  	n := uint32(50)
    45  	for {
    46  		b := make([]uint16, n)
    47  		e = TranslateName(u, from, to, &b[0], &n)
    48  		if e == nil {
    49  			return UTF16ToString(b[:n]), nil
    50  		}
    51  		if e != ERROR_INSUFFICIENT_BUFFER {
    52  			return "", e
    53  		}
    54  		if n <= uint32(len(b)) {
    55  			return "", e
    56  		}
    57  	}
    58  }
    59  
    60  const (
    61  	// do not reorder
    62  	NetSetupUnknownStatus = iota
    63  	NetSetupUnjoined
    64  	NetSetupWorkgroupName
    65  	NetSetupDomainName
    66  )
    67  
    68  type UserInfo10 struct {
    69  	Name       *uint16
    70  	Comment    *uint16
    71  	UsrComment *uint16
    72  	FullName   *uint16
    73  }
    74  
    75  //sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
    76  //sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
    77  //sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
    78  
    79  const (
    80  	// do not reorder
    81  	SidTypeUser = 1 + iota
    82  	SidTypeGroup
    83  	SidTypeDomain
    84  	SidTypeAlias
    85  	SidTypeWellKnownGroup
    86  	SidTypeDeletedAccount
    87  	SidTypeInvalid
    88  	SidTypeUnknown
    89  	SidTypeComputer
    90  	SidTypeLabel
    91  )
    92  
    93  //sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
    94  //sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
    95  //sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
    96  //sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
    97  //sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
    98  //sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
    99  
   100  // The security identifier (SID) structure is a variable-length
   101  // structure used to uniquely identify users or groups.
   102  type SID struct{}
   103  
   104  // StringToSid converts a string-format security identifier
   105  // sid into a valid, functional sid.
   106  func StringToSid(s string) (*SID, error) {
   107  	var sid *SID
   108  	p, e := UTF16PtrFromString(s)
   109  	if e != nil {
   110  		return nil, e
   111  	}
   112  	e = ConvertStringSidToSid(p, &sid)
   113  	if e != nil {
   114  		return nil, e
   115  	}
   116  	defer LocalFree((Handle)(unsafe.Pointer(sid)))
   117  	return sid.Copy()
   118  }
   119  
   120  // LookupSID retrieves a security identifier sid for the account
   121  // and the name of the domain on which the account was found.
   122  // System specify target computer to search.
   123  func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
   124  	if len(account) == 0 {
   125  		return nil, "", 0, EINVAL
   126  	}
   127  	acc, e := UTF16PtrFromString(account)
   128  	if e != nil {
   129  		return nil, "", 0, e
   130  	}
   131  	var sys *uint16
   132  	if len(system) > 0 {
   133  		sys, e = UTF16PtrFromString(system)
   134  		if e != nil {
   135  			return nil, "", 0, e
   136  		}
   137  	}
   138  	n := uint32(50)
   139  	dn := uint32(50)
   140  	for {
   141  		b := make([]byte, n)
   142  		db := make([]uint16, dn)
   143  		sid = (*SID)(unsafe.Pointer(&b[0]))
   144  		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
   145  		if e == nil {
   146  			return sid, UTF16ToString(db), accType, nil
   147  		}
   148  		if e != ERROR_INSUFFICIENT_BUFFER {
   149  			return nil, "", 0, e
   150  		}
   151  		if n <= uint32(len(b)) {
   152  			return nil, "", 0, e
   153  		}
   154  	}
   155  }
   156  
   157  // String converts sid to a string format
   158  // suitable for display, storage, or transmission.
   159  func (sid *SID) String() (string, error) {
   160  	var s *uint16
   161  	e := ConvertSidToStringSid(sid, &s)
   162  	if e != nil {
   163  		return "", e
   164  	}
   165  	defer LocalFree((Handle)(unsafe.Pointer(s)))
   166  	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
   167  }
   168  
   169  // Len returns the length, in bytes, of a valid security identifier sid.
   170  func (sid *SID) Len() int {
   171  	return int(GetLengthSid(sid))
   172  }
   173  
   174  // Copy creates a duplicate of security identifier sid.
   175  func (sid *SID) Copy() (*SID, error) {
   176  	b := make([]byte, sid.Len())
   177  	sid2 := (*SID)(unsafe.Pointer(&b[0]))
   178  	e := CopySid(uint32(len(b)), sid2, sid)
   179  	if e != nil {
   180  		return nil, e
   181  	}
   182  	return sid2, nil
   183  }
   184  
   185  // LookupAccount retrieves the name of the account for this sid
   186  // and the name of the first domain on which this sid is found.
   187  // System specify target computer to search for.
   188  func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
   189  	var sys *uint16
   190  	if len(system) > 0 {
   191  		sys, err = UTF16PtrFromString(system)
   192  		if err != nil {
   193  			return "", "", 0, err
   194  		}
   195  	}
   196  	n := uint32(50)
   197  	dn := uint32(50)
   198  	for {
   199  		b := make([]uint16, n)
   200  		db := make([]uint16, dn)
   201  		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
   202  		if e == nil {
   203  			return UTF16ToString(b), UTF16ToString(db), accType, nil
   204  		}
   205  		if e != ERROR_INSUFFICIENT_BUFFER {
   206  			return "", "", 0, e
   207  		}
   208  		if n <= uint32(len(b)) {
   209  			return "", "", 0, e
   210  		}
   211  	}
   212  }
   213  
   214  const (
   215  	// do not reorder
   216  	TOKEN_ASSIGN_PRIMARY = 1 << iota
   217  	TOKEN_DUPLICATE
   218  	TOKEN_IMPERSONATE
   219  	TOKEN_QUERY
   220  	TOKEN_QUERY_SOURCE
   221  	TOKEN_ADJUST_PRIVILEGES
   222  	TOKEN_ADJUST_GROUPS
   223  	TOKEN_ADJUST_DEFAULT
   224  
   225  	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
   226  		TOKEN_ASSIGN_PRIMARY |
   227  		TOKEN_DUPLICATE |
   228  		TOKEN_IMPERSONATE |
   229  		TOKEN_QUERY |
   230  		TOKEN_QUERY_SOURCE |
   231  		TOKEN_ADJUST_PRIVILEGES |
   232  		TOKEN_ADJUST_GROUPS |
   233  		TOKEN_ADJUST_DEFAULT
   234  	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
   235  	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
   236  		TOKEN_ADJUST_PRIVILEGES |
   237  		TOKEN_ADJUST_GROUPS |
   238  		TOKEN_ADJUST_DEFAULT
   239  	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
   240  )
   241  
   242  const (
   243  	// do not reorder
   244  	TokenUser = 1 + iota
   245  	TokenGroups
   246  	TokenPrivileges
   247  	TokenOwner
   248  	TokenPrimaryGroup
   249  	TokenDefaultDacl
   250  	TokenSource
   251  	TokenType
   252  	TokenImpersonationLevel
   253  	TokenStatistics
   254  	TokenRestrictedSids
   255  	TokenSessionId
   256  	TokenGroupsAndPrivileges
   257  	TokenSessionReference
   258  	TokenSandBoxInert
   259  	TokenAuditPolicy
   260  	TokenOrigin
   261  	TokenElevationType
   262  	TokenLinkedToken
   263  	TokenElevation
   264  	TokenHasRestrictions
   265  	TokenAccessInformation
   266  	TokenVirtualizationAllowed
   267  	TokenVirtualizationEnabled
   268  	TokenIntegrityLevel
   269  	TokenUIAccess
   270  	TokenMandatoryPolicy
   271  	TokenLogonSid
   272  	MaxTokenInfoClass
   273  )
   274  
   275  type SIDAndAttributes struct {
   276  	Sid        *SID
   277  	Attributes uint32
   278  }
   279  
   280  type Tokenuser struct {
   281  	User SIDAndAttributes
   282  }
   283  
   284  type Tokenprimarygroup struct {
   285  	PrimaryGroup *SID
   286  }
   287  
   288  //sys	OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
   289  //sys	GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
   290  //sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
   291  
   292  // An access token contains the security information for a logon session.
   293  // The system creates an access token when a user logs on, and every
   294  // process executed on behalf of the user has a copy of the token.
   295  // The token identifies the user, the user's groups, and the user's
   296  // privileges. The system uses the token to control access to securable
   297  // objects and to control the ability of the user to perform various
   298  // system-related operations on the local computer.
   299  type Token Handle
   300  
   301  // OpenCurrentProcessToken opens the access token
   302  // associated with current process.
   303  func OpenCurrentProcessToken() (Token, error) {
   304  	p, e := GetCurrentProcess()
   305  	if e != nil {
   306  		return 0, e
   307  	}
   308  	var t Token
   309  	e = OpenProcessToken(p, TOKEN_QUERY, &t)
   310  	if e != nil {
   311  		return 0, e
   312  	}
   313  	return t, nil
   314  }
   315  
   316  // Close releases access to access token.
   317  func (t Token) Close() error {
   318  	return CloseHandle(Handle(t))
   319  }
   320  
   321  // getInfo retrieves a specified type of information about an access token.
   322  func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
   323  	n := uint32(initSize)
   324  	for {
   325  		b := make([]byte, n)
   326  		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
   327  		if e == nil {
   328  			return unsafe.Pointer(&b[0]), nil
   329  		}
   330  		if e != ERROR_INSUFFICIENT_BUFFER {
   331  			return nil, e
   332  		}
   333  		if n <= uint32(len(b)) {
   334  			return nil, e
   335  		}
   336  	}
   337  }
   338  
   339  // GetTokenUser retrieves access token t user account information.
   340  func (t Token) GetTokenUser() (*Tokenuser, error) {
   341  	i, e := t.getInfo(TokenUser, 50)
   342  	if e != nil {
   343  		return nil, e
   344  	}
   345  	return (*Tokenuser)(i), nil
   346  }
   347  
   348  // GetTokenPrimaryGroup retrieves access token t primary group information.
   349  // A pointer to a SID structure representing a group that will become
   350  // the primary group of any objects created by a process using this access token.
   351  func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
   352  	i, e := t.getInfo(TokenPrimaryGroup, 50)
   353  	if e != nil {
   354  		return nil, e
   355  	}
   356  	return (*Tokenprimarygroup)(i), nil
   357  }
   358  
   359  // GetUserProfileDirectory retrieves path to the
   360  // root directory of the access token t user's profile.
   361  func (t Token) GetUserProfileDirectory() (string, error) {
   362  	n := uint32(100)
   363  	for {
   364  		b := make([]uint16, n)
   365  		e := GetUserProfileDirectory(t, &b[0], &n)
   366  		if e == nil {
   367  			return UTF16ToString(b), nil
   368  		}
   369  		if e != ERROR_INSUFFICIENT_BUFFER {
   370  			return "", e
   371  		}
   372  		if n <= uint32(len(b)) {
   373  			return "", e
   374  		}
   375  	}
   376  }