github.com/puellanivis/breton@v0.2.16/lib/os/user/lookup_windows.go (about)

     1  // Code generated by Uses Names with Id instead of ID. DO NOT EDIT.
     2  // The above line skips linter because we use functions with the name Id instead of ID, but the linter refuses to allow this.
     3  // Copyright 2012 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package user
     8  
     9  import (
    10  	"errors"
    11  	"fmt"
    12  	"syscall"
    13  	"unsafe"
    14  )
    15  
    16  func init() {
    17  	groupImplemented = false
    18  }
    19  
    20  func isDomainJoined() (bool, error) {
    21  	var domain *uint16
    22  	var status uint32
    23  	err := syscall.NetGetJoinInformation(nil, &domain, &status)
    24  	if err != nil {
    25  		return false, err
    26  	}
    27  	syscall.NetApiBufferFree((*byte)(unsafe.Pointer(domain)))
    28  	return status == syscall.NetSetupDomainName, nil
    29  }
    30  
    31  func lookupFullNameDomain(domainAndUser string) (string, error) {
    32  	return syscall.TranslateAccountName(domainAndUser,
    33  		syscall.NameSamCompatible, syscall.NameDisplay, 50)
    34  }
    35  
    36  func lookupFullNameServer(servername, username string) (string, error) {
    37  	s, e := syscall.UTF16PtrFromString(servername)
    38  	if e != nil {
    39  		return "", e
    40  	}
    41  	u, e := syscall.UTF16PtrFromString(username)
    42  	if e != nil {
    43  		return "", e
    44  	}
    45  	var p *byte
    46  	e = syscall.NetUserGetInfo(s, u, 10, &p)
    47  	if e != nil {
    48  		return "", e
    49  	}
    50  	defer syscall.NetApiBufferFree(p)
    51  	i := (*syscall.UserInfo10)(unsafe.Pointer(p))
    52  	if i.FullName == nil {
    53  		return "", nil
    54  	}
    55  	name := syscall.UTF16ToString((*[1024]uint16)(unsafe.Pointer(i.FullName))[:])
    56  	return name, nil
    57  }
    58  
    59  func lookupFullName(domain, username, domainAndUser string) (string, error) {
    60  	name, err := lookupFullNameServer(domain, username)
    61  	if err == nil {
    62  		return name, nil
    63  	}
    64  
    65  	joined, err := isDomainJoined()
    66  	if err == nil && joined {
    67  		name, err := lookupFullNameDomain(domainAndUser)
    68  		if err == nil {
    69  			return name, nil
    70  		}
    71  	}
    72  
    73  	// domain worked neither as a domain nor as a server
    74  	// could be domain server unavailable
    75  	// pretend username is fullname
    76  	return username, nil
    77  }
    78  
    79  func newUser(usid *syscall.SID, gid, dir string) (*User, error) {
    80  	username, domain, t, e := usid.LookupAccount("")
    81  	if e != nil {
    82  		return nil, e
    83  	}
    84  	if t != syscall.SidTypeUser {
    85  		return nil, fmt.Errorf("user: should be user account type, not %d", t)
    86  	}
    87  	domainAndUser := domain + `\` + username
    88  	uid, e := usid.String()
    89  	if e != nil {
    90  		return nil, e
    91  	}
    92  	name, e := lookupFullName(domain, username, domainAndUser)
    93  	if e != nil {
    94  		return nil, e
    95  	}
    96  	u := &User{
    97  		Uid:      uid,
    98  		Gid:      gid,
    99  		Username: domainAndUser,
   100  		Name:     name,
   101  		HomeDir:  dir,
   102  	}
   103  	return u, nil
   104  }
   105  
   106  // CurrentUsername returns the username of the current user.
   107  func CurrentUsername() (string, error) {
   108  	t, e := syscall.OpenCurrentProcessToken()
   109  	if e != nil {
   110  		return "", e
   111  	}
   112  	defer t.Close()
   113  
   114  	u, e := t.GetTokenUser()
   115  	if e != nil {
   116  		return "", e
   117  	}
   118  
   119  	username, domain, ut, e := u.User.Sid.LookupAccount("")
   120  	if e != nil {
   121  		return "", e
   122  	}
   123  	if ut != syscall.SidTypeUser {
   124  		return "", fmt.Errorf("user: should be user account type, not %d", t)
   125  	}
   126  
   127  	return domain + `\` + username, nil
   128  }
   129  
   130  // CurrentHomeDir returns the home directory of the current user.
   131  func CurrentHomeDir() (string, error) {
   132  	t, e := syscall.OpenCurrentProcessToken()
   133  	if e != nil {
   134  		return "", e
   135  	}
   136  	defer t.Close()
   137  
   138  	return t.GetUserProfileDirectory()
   139  }
   140  
   141  func current() (*User, error) {
   142  	t, e := syscall.OpenCurrentProcessToken()
   143  	if e != nil {
   144  		return nil, e
   145  	}
   146  	defer t.Close()
   147  	u, e := t.GetTokenUser()
   148  	if e != nil {
   149  		return nil, e
   150  	}
   151  	pg, e := t.GetTokenPrimaryGroup()
   152  	if e != nil {
   153  		return nil, e
   154  	}
   155  	gid, e := pg.PrimaryGroup.String()
   156  	if e != nil {
   157  		return nil, e
   158  	}
   159  	dir, e := t.GetUserProfileDirectory()
   160  	if e != nil {
   161  		return nil, e
   162  	}
   163  	return newUser(u.User.Sid, gid, dir)
   164  }
   165  
   166  // BUG(brainman): Lookup and LookupId functions do not set
   167  // Gid and HomeDir fields in the User struct returned on windows.
   168  
   169  func newUserFromSid(usid *syscall.SID) (*User, error) {
   170  	// TODO(brainman): do not know where to get gid and dir fields
   171  	gid := "unknown"
   172  	dir := "Unknown directory"
   173  	return newUser(usid, gid, dir)
   174  }
   175  
   176  func lookupUser(username string) (*User, error) {
   177  	sid, _, t, e := syscall.LookupSID("", username)
   178  	if e != nil {
   179  		return nil, e
   180  	}
   181  	if t != syscall.SidTypeUser {
   182  		return nil, fmt.Errorf("user: should be user account type, not %d", t)
   183  	}
   184  	return newUserFromSid(sid)
   185  }
   186  
   187  func lookupUserId(uid string) (*User, error) {
   188  	sid, e := syscall.StringToSid(uid)
   189  	if e != nil {
   190  		return nil, e
   191  	}
   192  	return newUserFromSid(sid)
   193  }
   194  
   195  func lookupGroup(groupname string) (*Group, error) {
   196  	return nil, errors.New("user: LookupGroup not implemented on windows")
   197  }
   198  
   199  func lookupGroupId(string) (*Group, error) {
   200  	return nil, errors.New("user: LookupGroupId not implemented on windows")
   201  }
   202  
   203  func listGroups(*User) ([]string, error) {
   204  	return nil, errors.New("user: GroupIds not implemented on windows")
   205  }