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