...

Source file src/pkg/syscall/security_windows.go

     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	// https://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		TOKEN_ADJUST_SESSIONID
   225	
   226		TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
   227			TOKEN_ASSIGN_PRIMARY |
   228			TOKEN_DUPLICATE |
   229			TOKEN_IMPERSONATE |
   230			TOKEN_QUERY |
   231			TOKEN_QUERY_SOURCE |
   232			TOKEN_ADJUST_PRIVILEGES |
   233			TOKEN_ADJUST_GROUPS |
   234			TOKEN_ADJUST_DEFAULT |
   235			TOKEN_ADJUST_SESSIONID
   236		TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
   237		TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
   238			TOKEN_ADJUST_PRIVILEGES |
   239			TOKEN_ADJUST_GROUPS |
   240			TOKEN_ADJUST_DEFAULT
   241		TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
   242	)
   243	
   244	const (
   245		// do not reorder
   246		TokenUser = 1 + iota
   247		TokenGroups
   248		TokenPrivileges
   249		TokenOwner
   250		TokenPrimaryGroup
   251		TokenDefaultDacl
   252		TokenSource
   253		TokenType
   254		TokenImpersonationLevel
   255		TokenStatistics
   256		TokenRestrictedSids
   257		TokenSessionId
   258		TokenGroupsAndPrivileges
   259		TokenSessionReference
   260		TokenSandBoxInert
   261		TokenAuditPolicy
   262		TokenOrigin
   263		TokenElevationType
   264		TokenLinkedToken
   265		TokenElevation
   266		TokenHasRestrictions
   267		TokenAccessInformation
   268		TokenVirtualizationAllowed
   269		TokenVirtualizationEnabled
   270		TokenIntegrityLevel
   271		TokenUIAccess
   272		TokenMandatoryPolicy
   273		TokenLogonSid
   274		MaxTokenInfoClass
   275	)
   276	
   277	type SIDAndAttributes struct {
   278		Sid        *SID
   279		Attributes uint32
   280	}
   281	
   282	type Tokenuser struct {
   283		User SIDAndAttributes
   284	}
   285	
   286	type Tokenprimarygroup struct {
   287		PrimaryGroup *SID
   288	}
   289	
   290	//sys	OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
   291	//sys	GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
   292	//sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
   293	//sys	getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
   294	
   295	// An access token contains the security information for a logon session.
   296	// The system creates an access token when a user logs on, and every
   297	// process executed on behalf of the user has a copy of the token.
   298	// The token identifies the user, the user's groups, and the user's
   299	// privileges. The system uses the token to control access to securable
   300	// objects and to control the ability of the user to perform various
   301	// system-related operations on the local computer.
   302	type Token Handle
   303	
   304	// OpenCurrentProcessToken opens the access token
   305	// associated with current process.
   306	func OpenCurrentProcessToken() (Token, error) {
   307		p, e := GetCurrentProcess()
   308		if e != nil {
   309			return 0, e
   310		}
   311		var t Token
   312		e = OpenProcessToken(p, TOKEN_QUERY, &t)
   313		if e != nil {
   314			return 0, e
   315		}
   316		return t, nil
   317	}
   318	
   319	// Close releases access to access token.
   320	func (t Token) Close() error {
   321		return CloseHandle(Handle(t))
   322	}
   323	
   324	// getInfo retrieves a specified type of information about an access token.
   325	func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
   326		n := uint32(initSize)
   327		for {
   328			b := make([]byte, n)
   329			e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
   330			if e == nil {
   331				return unsafe.Pointer(&b[0]), nil
   332			}
   333			if e != ERROR_INSUFFICIENT_BUFFER {
   334				return nil, e
   335			}
   336			if n <= uint32(len(b)) {
   337				return nil, e
   338			}
   339		}
   340	}
   341	
   342	// GetTokenUser retrieves access token t user account information.
   343	func (t Token) GetTokenUser() (*Tokenuser, error) {
   344		i, e := t.getInfo(TokenUser, 50)
   345		if e != nil {
   346			return nil, e
   347		}
   348		return (*Tokenuser)(i), nil
   349	}
   350	
   351	// GetTokenPrimaryGroup retrieves access token t primary group information.
   352	// A pointer to a SID structure representing a group that will become
   353	// the primary group of any objects created by a process using this access token.
   354	func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
   355		i, e := t.getInfo(TokenPrimaryGroup, 50)
   356		if e != nil {
   357			return nil, e
   358		}
   359		return (*Tokenprimarygroup)(i), nil
   360	}
   361	
   362	// GetUserProfileDirectory retrieves path to the
   363	// root directory of the access token t user's profile.
   364	func (t Token) GetUserProfileDirectory() (string, error) {
   365		n := uint32(100)
   366		for {
   367			b := make([]uint16, n)
   368			e := GetUserProfileDirectory(t, &b[0], &n)
   369			if e == nil {
   370				return UTF16ToString(b), nil
   371			}
   372			if e != ERROR_INSUFFICIENT_BUFFER {
   373				return "", e
   374			}
   375			if n <= uint32(len(b)) {
   376				return "", e
   377			}
   378		}
   379	}
   380	

View as plain text