github.com/go-xe2/third@v1.0.3/golang.org/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  // Predefined domain-relative RIDs for local groups.
   136  // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379649(v=vs.85).aspx
   137  const (
   138  	DOMAIN_ALIAS_RID_ADMINS                         = 0x220
   139  	DOMAIN_ALIAS_RID_USERS                          = 0x221
   140  	DOMAIN_ALIAS_RID_GUESTS                         = 0x222
   141  	DOMAIN_ALIAS_RID_POWER_USERS                    = 0x223
   142  	DOMAIN_ALIAS_RID_ACCOUNT_OPS                    = 0x224
   143  	DOMAIN_ALIAS_RID_SYSTEM_OPS                     = 0x225
   144  	DOMAIN_ALIAS_RID_PRINT_OPS                      = 0x226
   145  	DOMAIN_ALIAS_RID_BACKUP_OPS                     = 0x227
   146  	DOMAIN_ALIAS_RID_REPLICATOR                     = 0x228
   147  	DOMAIN_ALIAS_RID_RAS_SERVERS                    = 0x229
   148  	DOMAIN_ALIAS_RID_PREW2KCOMPACCESS               = 0x22a
   149  	DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS           = 0x22b
   150  	DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS      = 0x22c
   151  	DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS = 0x22d
   152  	DOMAIN_ALIAS_RID_MONITORING_USERS               = 0x22e
   153  	DOMAIN_ALIAS_RID_LOGGING_USERS                  = 0x22f
   154  	DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS            = 0x230
   155  	DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS             = 0x231
   156  	DOMAIN_ALIAS_RID_DCOM_USERS                     = 0x232
   157  	DOMAIN_ALIAS_RID_IUSERS                         = 0x238
   158  	DOMAIN_ALIAS_RID_CRYPTO_OPERATORS               = 0x239
   159  	DOMAIN_ALIAS_RID_CACHEABLE_PRINCIPALS_GROUP     = 0x23b
   160  	DOMAIN_ALIAS_RID_NON_CACHEABLE_PRINCIPALS_GROUP = 0x23c
   161  	DOMAIN_ALIAS_RID_EVENT_LOG_READERS_GROUP        = 0x23d
   162  	DOMAIN_ALIAS_RID_CERTSVC_DCOM_ACCESS_GROUP      = 0x23e
   163  )
   164  
   165  //sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
   166  //sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
   167  //sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
   168  //sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
   169  //sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
   170  //sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
   171  //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
   172  //sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
   173  //sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
   174  
   175  // The security identifier (SID) structure is a variable-length
   176  // structure used to uniquely identify users or groups.
   177  type SID struct{}
   178  
   179  // StringToSid converts a string-format security identifier
   180  // sid into a valid, functional sid.
   181  func StringToSid(s string) (*SID, error) {
   182  	var sid *SID
   183  	p, e := UTF16PtrFromString(s)
   184  	if e != nil {
   185  		return nil, e
   186  	}
   187  	e = ConvertStringSidToSid(p, &sid)
   188  	if e != nil {
   189  		return nil, e
   190  	}
   191  	defer LocalFree((Handle)(unsafe.Pointer(sid)))
   192  	return sid.Copy()
   193  }
   194  
   195  // LookupSID retrieves a security identifier sid for the account
   196  // and the name of the domain on which the account was found.
   197  // System specify target computer to search.
   198  func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
   199  	if len(account) == 0 {
   200  		return nil, "", 0, syscall.EINVAL
   201  	}
   202  	acc, e := UTF16PtrFromString(account)
   203  	if e != nil {
   204  		return nil, "", 0, e
   205  	}
   206  	var sys *uint16
   207  	if len(system) > 0 {
   208  		sys, e = UTF16PtrFromString(system)
   209  		if e != nil {
   210  			return nil, "", 0, e
   211  		}
   212  	}
   213  	n := uint32(50)
   214  	dn := uint32(50)
   215  	for {
   216  		b := make([]byte, n)
   217  		db := make([]uint16, dn)
   218  		sid = (*SID)(unsafe.Pointer(&b[0]))
   219  		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
   220  		if e == nil {
   221  			return sid, UTF16ToString(db), accType, nil
   222  		}
   223  		if e != ERROR_INSUFFICIENT_BUFFER {
   224  			return nil, "", 0, e
   225  		}
   226  		if n <= uint32(len(b)) {
   227  			return nil, "", 0, e
   228  		}
   229  	}
   230  }
   231  
   232  // String converts sid to a string format
   233  // suitable for display, storage, or transmission.
   234  func (sid *SID) String() (string, error) {
   235  	var s *uint16
   236  	e := ConvertSidToStringSid(sid, &s)
   237  	if e != nil {
   238  		return "", e
   239  	}
   240  	defer LocalFree((Handle)(unsafe.Pointer(s)))
   241  	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
   242  }
   243  
   244  // Len returns the length, in bytes, of a valid security identifier sid.
   245  func (sid *SID) Len() int {
   246  	return int(GetLengthSid(sid))
   247  }
   248  
   249  // Copy creates a duplicate of security identifier sid.
   250  func (sid *SID) Copy() (*SID, error) {
   251  	b := make([]byte, sid.Len())
   252  	sid2 := (*SID)(unsafe.Pointer(&b[0]))
   253  	e := CopySid(uint32(len(b)), sid2, sid)
   254  	if e != nil {
   255  		return nil, e
   256  	}
   257  	return sid2, nil
   258  }
   259  
   260  // LookupAccount retrieves the name of the account for this sid
   261  // and the name of the first domain on which this sid is found.
   262  // System specify target computer to search for.
   263  func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
   264  	var sys *uint16
   265  	if len(system) > 0 {
   266  		sys, err = UTF16PtrFromString(system)
   267  		if err != nil {
   268  			return "", "", 0, err
   269  		}
   270  	}
   271  	n := uint32(50)
   272  	dn := uint32(50)
   273  	for {
   274  		b := make([]uint16, n)
   275  		db := make([]uint16, dn)
   276  		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
   277  		if e == nil {
   278  			return UTF16ToString(b), UTF16ToString(db), accType, nil
   279  		}
   280  		if e != ERROR_INSUFFICIENT_BUFFER {
   281  			return "", "", 0, e
   282  		}
   283  		if n <= uint32(len(b)) {
   284  			return "", "", 0, e
   285  		}
   286  	}
   287  }
   288  
   289  const (
   290  	// do not reorder
   291  	TOKEN_ASSIGN_PRIMARY = 1 << iota
   292  	TOKEN_DUPLICATE
   293  	TOKEN_IMPERSONATE
   294  	TOKEN_QUERY
   295  	TOKEN_QUERY_SOURCE
   296  	TOKEN_ADJUST_PRIVILEGES
   297  	TOKEN_ADJUST_GROUPS
   298  	TOKEN_ADJUST_DEFAULT
   299  	TOKEN_ADJUST_SESSIONID
   300  
   301  	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
   302  		TOKEN_ASSIGN_PRIMARY |
   303  		TOKEN_DUPLICATE |
   304  		TOKEN_IMPERSONATE |
   305  		TOKEN_QUERY |
   306  		TOKEN_QUERY_SOURCE |
   307  		TOKEN_ADJUST_PRIVILEGES |
   308  		TOKEN_ADJUST_GROUPS |
   309  		TOKEN_ADJUST_DEFAULT |
   310  		TOKEN_ADJUST_SESSIONID
   311  	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
   312  	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
   313  		TOKEN_ADJUST_PRIVILEGES |
   314  		TOKEN_ADJUST_GROUPS |
   315  		TOKEN_ADJUST_DEFAULT
   316  	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
   317  )
   318  
   319  const (
   320  	// do not reorder
   321  	TokenUser = 1 + iota
   322  	TokenGroups
   323  	TokenPrivileges
   324  	TokenOwner
   325  	TokenPrimaryGroup
   326  	TokenDefaultDacl
   327  	TokenSource
   328  	TokenType
   329  	TokenImpersonationLevel
   330  	TokenStatistics
   331  	TokenRestrictedSids
   332  	TokenSessionId
   333  	TokenGroupsAndPrivileges
   334  	TokenSessionReference
   335  	TokenSandBoxInert
   336  	TokenAuditPolicy
   337  	TokenOrigin
   338  	TokenElevationType
   339  	TokenLinkedToken
   340  	TokenElevation
   341  	TokenHasRestrictions
   342  	TokenAccessInformation
   343  	TokenVirtualizationAllowed
   344  	TokenVirtualizationEnabled
   345  	TokenIntegrityLevel
   346  	TokenUIAccess
   347  	TokenMandatoryPolicy
   348  	TokenLogonSid
   349  	MaxTokenInfoClass
   350  )
   351  
   352  type SIDAndAttributes struct {
   353  	Sid        *SID
   354  	Attributes uint32
   355  }
   356  
   357  type Tokenuser struct {
   358  	User SIDAndAttributes
   359  }
   360  
   361  type Tokenprimarygroup struct {
   362  	PrimaryGroup *SID
   363  }
   364  
   365  type Tokengroups struct {
   366  	GroupCount uint32
   367  	Groups     [1]SIDAndAttributes
   368  }
   369  
   370  // Authorization Functions
   371  //sys checkTokenMembership(tokenHandle Token, sidToCheck *SID, isMember *int32) (err error) = advapi32.CheckTokenMembership
   372  //sys	OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
   373  //sys	GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
   374  //sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
   375  
   376  // An access token contains the security information for a logon session.
   377  // The system creates an access token when a user logs on, and every
   378  // process executed on behalf of the user has a copy of the token.
   379  // The token identifies the user, the user's groups, and the user's
   380  // privileges. The system uses the token to control access to securable
   381  // objects and to control the ability of the user to perform various
   382  // system-related operations on the local computer.
   383  type Token Handle
   384  
   385  // OpenCurrentProcessToken opens the access token
   386  // associated with current process.
   387  func OpenCurrentProcessToken() (Token, error) {
   388  	p, e := GetCurrentProcess()
   389  	if e != nil {
   390  		return 0, e
   391  	}
   392  	var t Token
   393  	e = OpenProcessToken(p, TOKEN_QUERY, &t)
   394  	if e != nil {
   395  		return 0, e
   396  	}
   397  	return t, nil
   398  }
   399  
   400  // Close releases access to access token.
   401  func (t Token) Close() error {
   402  	return CloseHandle(Handle(t))
   403  }
   404  
   405  // getInfo retrieves a specified type of information about an access token.
   406  func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
   407  	n := uint32(initSize)
   408  	for {
   409  		b := make([]byte, n)
   410  		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
   411  		if e == nil {
   412  			return unsafe.Pointer(&b[0]), nil
   413  		}
   414  		if e != ERROR_INSUFFICIENT_BUFFER {
   415  			return nil, e
   416  		}
   417  		if n <= uint32(len(b)) {
   418  			return nil, e
   419  		}
   420  	}
   421  }
   422  
   423  // GetTokenUser retrieves access token t user account information.
   424  func (t Token) GetTokenUser() (*Tokenuser, error) {
   425  	i, e := t.getInfo(TokenUser, 50)
   426  	if e != nil {
   427  		return nil, e
   428  	}
   429  	return (*Tokenuser)(i), nil
   430  }
   431  
   432  // GetTokenGroups retrieves group accounts associated with access token t.
   433  func (t Token) GetTokenGroups() (*Tokengroups, error) {
   434  	i, e := t.getInfo(TokenGroups, 50)
   435  	if e != nil {
   436  		return nil, e
   437  	}
   438  	return (*Tokengroups)(i), nil
   439  }
   440  
   441  // GetTokenPrimaryGroup retrieves access token t primary group information.
   442  // A pointer to a SID structure representing a group that will become
   443  // the primary group of any objects created by a process using this access token.
   444  func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
   445  	i, e := t.getInfo(TokenPrimaryGroup, 50)
   446  	if e != nil {
   447  		return nil, e
   448  	}
   449  	return (*Tokenprimarygroup)(i), nil
   450  }
   451  
   452  // GetUserProfileDirectory retrieves path to the
   453  // root directory of the access token t user's profile.
   454  func (t Token) GetUserProfileDirectory() (string, error) {
   455  	n := uint32(100)
   456  	for {
   457  		b := make([]uint16, n)
   458  		e := GetUserProfileDirectory(t, &b[0], &n)
   459  		if e == nil {
   460  			return UTF16ToString(b), nil
   461  		}
   462  		if e != ERROR_INSUFFICIENT_BUFFER {
   463  			return "", e
   464  		}
   465  		if n <= uint32(len(b)) {
   466  			return "", e
   467  		}
   468  	}
   469  }
   470  
   471  // IsMember reports whether the access token t is a member of the provided SID.
   472  func (t Token) IsMember(sid *SID) (bool, error) {
   473  	var b int32
   474  	if e := checkTokenMembership(t, sid, &b); e != nil {
   475  		return false, e
   476  	}
   477  	return b != 0, nil
   478  }