...
Run Format

Source file src/os/user/lookup_windows.go

Documentation: os/user

  // 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 user
  
  import (
  	"errors"
  	"fmt"
  	"syscall"
  	"unsafe"
  )
  
  func init() {
  	groupImplemented = false
  }
  
  func isDomainJoined() (bool, error) {
  	var domain *uint16
  	var status uint32
  	err := syscall.NetGetJoinInformation(nil, &domain, &status)
  	if err != nil {
  		return false, err
  	}
  	syscall.NetApiBufferFree((*byte)(unsafe.Pointer(domain)))
  	return status == syscall.NetSetupDomainName, nil
  }
  
  func lookupFullNameDomain(domainAndUser string) (string, error) {
  	return syscall.TranslateAccountName(domainAndUser,
  		syscall.NameSamCompatible, syscall.NameDisplay, 50)
  }
  
  func lookupFullNameServer(servername, username string) (string, error) {
  	s, e := syscall.UTF16PtrFromString(servername)
  	if e != nil {
  		return "", e
  	}
  	u, e := syscall.UTF16PtrFromString(username)
  	if e != nil {
  		return "", e
  	}
  	var p *byte
  	e = syscall.NetUserGetInfo(s, u, 10, &p)
  	if e != nil {
  		return "", e
  	}
  	defer syscall.NetApiBufferFree(p)
  	i := (*syscall.UserInfo10)(unsafe.Pointer(p))
  	if i.FullName == nil {
  		return "", nil
  	}
  	name := syscall.UTF16ToString((*[1024]uint16)(unsafe.Pointer(i.FullName))[:])
  	return name, nil
  }
  
  func lookupFullName(domain, username, domainAndUser string) (string, error) {
  	joined, err := isDomainJoined()
  	if err == nil && joined {
  		name, err := lookupFullNameDomain(domainAndUser)
  		if err == nil {
  			return name, nil
  		}
  	}
  	name, err := lookupFullNameServer(domain, username)
  	if err == nil {
  		return name, nil
  	}
  	// domain worked neither as a domain nor as a server
  	// could be domain server unavailable
  	// pretend username is fullname
  	return username, nil
  }
  
  func newUser(usid *syscall.SID, gid, dir string) (*User, error) {
  	username, domain, t, e := usid.LookupAccount("")
  	if e != nil {
  		return nil, e
  	}
  	if t != syscall.SidTypeUser {
  		return nil, fmt.Errorf("user: should be user account type, not %d", t)
  	}
  	domainAndUser := domain + `\` + username
  	uid, e := usid.String()
  	if e != nil {
  		return nil, e
  	}
  	name, e := lookupFullName(domain, username, domainAndUser)
  	if e != nil {
  		return nil, e
  	}
  	u := &User{
  		Uid:      uid,
  		Gid:      gid,
  		Username: domainAndUser,
  		Name:     name,
  		HomeDir:  dir,
  	}
  	return u, nil
  }
  
  func current() (*User, error) {
  	t, e := syscall.OpenCurrentProcessToken()
  	if e != nil {
  		return nil, e
  	}
  	defer t.Close()
  	u, e := t.GetTokenUser()
  	if e != nil {
  		return nil, e
  	}
  	pg, e := t.GetTokenPrimaryGroup()
  	if e != nil {
  		return nil, e
  	}
  	gid, e := pg.PrimaryGroup.String()
  	if e != nil {
  		return nil, e
  	}
  	dir, e := t.GetUserProfileDirectory()
  	if e != nil {
  		return nil, e
  	}
  	return newUser(u.User.Sid, gid, dir)
  }
  
  // BUG(brainman): Lookup and LookupId functions do not set
  // Gid and HomeDir fields in the User struct returned on windows.
  
  func newUserFromSid(usid *syscall.SID) (*User, error) {
  	// TODO(brainman): do not know where to get gid and dir fields
  	gid := "unknown"
  	dir := "Unknown directory"
  	return newUser(usid, gid, dir)
  }
  
  func lookupUser(username string) (*User, error) {
  	sid, _, t, e := syscall.LookupSID("", username)
  	if e != nil {
  		return nil, e
  	}
  	if t != syscall.SidTypeUser {
  		return nil, fmt.Errorf("user: should be user account type, not %d", t)
  	}
  	return newUserFromSid(sid)
  }
  
  func lookupUserId(uid string) (*User, error) {
  	sid, e := syscall.StringToSid(uid)
  	if e != nil {
  		return nil, e
  	}
  	return newUserFromSid(sid)
  }
  
  func lookupGroup(groupname string) (*Group, error) {
  	return nil, errors.New("user: LookupGroup not implemented on windows")
  }
  
  func lookupGroupId(string) (*Group, error) {
  	return nil, errors.New("user: LookupGroupId not implemented on windows")
  }
  
  func listGroups(*User) ([]string, error) {
  	return nil, errors.New("user: GroupIds not implemented on windows")
  }
  

View as plain text