pkg.re/essentialkaos/ek.10@v12.41.0+incompatible/system/user_unix.go (about)

     1  //go:build linux || freebsd
     2  // +build linux freebsd
     3  
     4  package system
     5  
     6  // ////////////////////////////////////////////////////////////////////////////////// //
     7  //                                                                                    //
     8  //                         Copyright (c) 2022 ESSENTIAL KAOS                          //
     9  //      Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0>     //
    10  //                                                                                    //
    11  // ////////////////////////////////////////////////////////////////////////////////// //
    12  
    13  import (
    14  	"fmt"
    15  	"os/exec"
    16  	"strconv"
    17  	"strings"
    18  
    19  	"pkg.re/essentialkaos/ek.v12/strutil"
    20  )
    21  
    22  // ////////////////////////////////////////////////////////////////////////////////// //
    23  
    24  // IsUserExist checks if user exist on system or not
    25  func IsUserExist(name string) bool {
    26  	cmd := exec.Command("getent", "passwd", name)
    27  
    28  	return cmd.Run() == nil
    29  }
    30  
    31  // IsGroupExist checks if group exist on system or not
    32  func IsGroupExist(name string) bool {
    33  	cmd := exec.Command("getent", "group", name)
    34  
    35  	return cmd.Run() == nil
    36  }
    37  
    38  // ////////////////////////////////////////////////////////////////////////////////// //
    39  
    40  // getUserInfo tries to find user info by name or UID
    41  func getUserInfo(nameOrID string) (*User, error) {
    42  	cmd := exec.Command("getent", "passwd", nameOrID)
    43  
    44  	data, err := cmd.Output()
    45  
    46  	if err != nil {
    47  		return nil, fmt.Errorf("User with name/ID %s does not exist", nameOrID)
    48  	}
    49  
    50  	return parseGetentPasswdOutput(string(data))
    51  }
    52  
    53  // getGroupInfo returns group info by name or id
    54  func getGroupInfo(nameOrID string) (*Group, error) {
    55  	cmd := exec.Command("getent", "group", nameOrID)
    56  
    57  	data, err := cmd.Output()
    58  
    59  	if err != nil {
    60  		return nil, fmt.Errorf("Group with name/ID %s does not exist", nameOrID)
    61  	}
    62  
    63  	return parseGetentGroupOutput(string(data))
    64  }
    65  
    66  // parseGetentGroupOutput parse 'getent passwd' command output
    67  func parseGetentPasswdOutput(data string) (*User, error) {
    68  	data = strings.TrimRight(data, "\r\n")
    69  
    70  	uid, err := strconv.Atoi(strutil.ReadField(data, 2, false, ":"))
    71  
    72  	if err != nil {
    73  		return nil, ErrCantParseGetentOutput
    74  	}
    75  
    76  	gid, err := strconv.Atoi(strutil.ReadField(data, 3, false, ":"))
    77  
    78  	if err != nil {
    79  		return nil, ErrCantParseGetentOutput
    80  	}
    81  
    82  	return &User{
    83  		Name:     strutil.ReadField(data, 0, false, ":"),
    84  		UID:      uid,
    85  		GID:      gid,
    86  		Comment:  strutil.ReadField(data, 4, false, ":"),
    87  		HomeDir:  strutil.ReadField(data, 5, false, ":"),
    88  		Shell:    strutil.ReadField(data, 6, false, ":"),
    89  		RealName: strutil.ReadField(data, 0, false, ":"),
    90  		RealUID:  uid,
    91  		RealGID:  gid,
    92  	}, nil
    93  }
    94  
    95  // parseGetentGroupOutput parse 'getent group' command output
    96  func parseGetentGroupOutput(data string) (*Group, error) {
    97  	name := strutil.ReadField(data, 0, false, ":")
    98  	id := strutil.ReadField(data, 2, false, ":")
    99  
   100  	if name == "" || id == "" {
   101  		return nil, ErrCantParseGetentOutput
   102  	}
   103  
   104  	gid, err := strconv.Atoi(id)
   105  
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	return &Group{name, gid}, nil
   111  }