go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/users/ps1getlocalusers.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package users
     5  
     6  import (
     7  	"encoding/json"
     8  	"io"
     9  
    10  	"go.mondoo.com/cnquery/providers/os/connection/shared"
    11  	"go.mondoo.com/cnquery/providers/os/resources/powershell"
    12  )
    13  
    14  type WindowsSID struct {
    15  	BinaryLength     int
    16  	AccountDomainSid *string
    17  	Value            string
    18  }
    19  
    20  // NOTE: there is some overlap with windows groups
    21  type WindowsLocalUser struct {
    22  	// same values as in group
    23  	Name            string
    24  	Description     string
    25  	PrincipalSource int
    26  	SID             WindowsSID
    27  	ObjectClass     string
    28  
    29  	// special attributes for user
    30  	Enabled                bool
    31  	FullName               string
    32  	PasswordRequired       bool
    33  	UserMayChangePassword  bool
    34  	AccountExpires         *string
    35  	PasswordChangeableDate *string
    36  	PasswordExpires        *string
    37  	PasswordLastSet        *string
    38  	LastLogon              *string
    39  }
    40  
    41  func ParseWindowsLocalUsers(r io.Reader) ([]WindowsLocalUser, error) {
    42  	data, err := io.ReadAll(r)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	var localUsers []WindowsLocalUser
    48  	err = json.Unmarshal(data, &localUsers)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  
    53  	return localUsers, nil
    54  }
    55  
    56  type WindowsUserManager struct {
    57  	conn shared.Connection
    58  }
    59  
    60  func (s *WindowsUserManager) Name() string {
    61  	return "Windows User Manager"
    62  }
    63  
    64  func (s *WindowsUserManager) User(id string) (*User, error) {
    65  	users, err := s.List()
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	return findUser(users, id)
    71  }
    72  
    73  func (s *WindowsUserManager) List() ([]*User, error) {
    74  	powershellCmd := "Get-LocalUser | ConvertTo-Json"
    75  	c, err := s.conn.RunCommand(powershell.Wrap(powershellCmd))
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  	winUsers, err := ParseWindowsLocalUsers(c.Stdout)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  
    84  	res := []*User{}
    85  	for i := range winUsers {
    86  		res = append(res, winToUser(winUsers[i]))
    87  	}
    88  	return res, nil
    89  }
    90  
    91  func winToUser(g WindowsLocalUser) *User {
    92  	// TODO: consider to store additional attributes in key-value pairs
    93  	return &User{
    94  		ID:      g.SID.Value,
    95  		Sid:     g.SID.Value,
    96  		Uid:     -1, // TODO: not its suboptimal, but lets make sure to avoid runtime conflicts for now
    97  		Gid:     -1,
    98  		Name:    g.Name,
    99  		Enabled: g.Enabled,
   100  	}
   101  }