github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/core/id/users.go (about)

     1  // Copyright 2017-2018 the u-root 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  //go:build !plan9
     6  // +build !plan9
     7  
     8  package main
     9  
    10  import (
    11  	"bufio"
    12  	"fmt"
    13  	"os"
    14  	"strconv"
    15  	"strings"
    16  )
    17  
    18  // Users manages a user database, typically loaded from /etc/passwd
    19  type Users struct {
    20  	uidToUser map[int]string
    21  	userToUID map[string]int
    22  	userToGID map[int]int
    23  }
    24  
    25  // GetUID returns the UID of a username
    26  func (u *Users) GetUID(name string) (int, error) {
    27  	if v, ok := u.userToUID[name]; ok {
    28  		return v, nil
    29  	}
    30  	return -1, fmt.Errorf("unknown user name: %s", name)
    31  }
    32  
    33  // GetGID returns the primary GID of a UID
    34  func (u *Users) GetGID(uid int) (int, error) {
    35  	if v, ok := u.userToGID[uid]; ok {
    36  		return v, nil
    37  	}
    38  	return -1, fmt.Errorf("unknown uid: %d", uid)
    39  }
    40  
    41  // GetUser returns the username of a UID
    42  func (u *Users) GetUser(uid int) (string, error) {
    43  	if v, ok := u.uidToUser[uid]; ok {
    44  		return v, nil
    45  	}
    46  	return "", fmt.Errorf("unkown uid: %d", uid)
    47  }
    48  
    49  // NewUsers is a factory for Users.  file is the file to read the database from.
    50  func NewUsers(file string) (u *Users, e error) {
    51  	u = &Users{}
    52  	u.uidToUser = make(map[int]string)
    53  	u.userToUID = make(map[string]int)
    54  	u.userToGID = make(map[int]int)
    55  
    56  	passwdFile, err := os.Open(file)
    57  	if err != nil {
    58  		return u, err
    59  	}
    60  
    61  	// Read from passwdFile for the users name
    62  	var passwdInfo []string
    63  
    64  	passwdScanner := bufio.NewScanner(passwdFile)
    65  
    66  	for passwdScanner.Scan() {
    67  		txt := passwdScanner.Text()
    68  		if len(txt) == 0 || txt[0] == '#' { // skip empty lines and comments
    69  			continue
    70  		}
    71  		passwdInfo = strings.Split(txt, ":")
    72  		userNum, err := strconv.Atoi(passwdInfo[2])
    73  		if err != nil {
    74  			return nil, err
    75  		}
    76  		groupNum, err := strconv.Atoi(passwdInfo[3])
    77  		if err != nil {
    78  			return nil, err
    79  		}
    80  
    81  		u.uidToUser[userNum] = passwdInfo[0]
    82  		u.userToUID[passwdInfo[0]] = userNum
    83  		u.userToGID[userNum] = groupNum
    84  	}
    85  
    86  	return
    87  }