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

     1  package system
     2  
     3  // ////////////////////////////////////////////////////////////////////////////////// //
     4  //                                                                                    //
     5  //                         Copyright (c) 2022 ESSENTIAL KAOS                          //
     6  //      Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0>     //
     7  //                                                                                    //
     8  // ////////////////////////////////////////////////////////////////////////////////// //
     9  
    10  import (
    11  	"bufio"
    12  	"fmt"
    13  	"os/exec"
    14  	"strconv"
    15  	"strings"
    16  
    17  	"pkg.re/essentialkaos/ek.v12/strutil"
    18  )
    19  
    20  // ////////////////////////////////////////////////////////////////////////////////// //
    21  
    22  // IsUserExist checks if user exist on system or not
    23  func IsUserExist(name string) bool {
    24  	cmd := exec.Command("dscl", ".", "-read", "/Users/"+name, "RecordName")
    25  
    26  	return cmd.Run() == nil
    27  }
    28  
    29  // IsGroupExist checks if group exist on system or not
    30  func IsGroupExist(name string) bool {
    31  	cmd := exec.Command("dscl", ".", "-read", "/Groups/"+name, "RecordName")
    32  
    33  	return cmd.Run() == nil
    34  }
    35  
    36  // ////////////////////////////////////////////////////////////////////////////////// //
    37  
    38  // getUserInfo tries to find user info by name
    39  func getUserInfo(name string) (*User, error) {
    40  	cmd := exec.Command(
    41  		"dscl", ".", "-read", "/Users/"+name,
    42  		"UniqueID", "PrimaryGroupID", "NFSHomeDirectory", "UserShell",
    43  	)
    44  
    45  	out, err := cmd.Output()
    46  
    47  	if err != nil || len(out) == 0 {
    48  		return nil, fmt.Errorf("User with name %s does not exist", name)
    49  	}
    50  
    51  	user := &User{Name: name, RealName: name}
    52  	scanner := bufio.NewScanner(strings.NewReader(string(out)))
    53  
    54  	for scanner.Scan() {
    55  		line := scanner.Text()
    56  		field := strutil.ReadField(line, 0, false, ":")
    57  
    58  		switch field {
    59  		case "UniqueID":
    60  			user.UID, err = strconv.Atoi(strings.TrimSpace(strutil.ReadField(line, 1, false, ":")))
    61  		case "PrimaryGroupID":
    62  			user.GID, err = strconv.Atoi(strings.TrimSpace(strutil.ReadField(line, 1, false, ":")))
    63  		case "NFSHomeDirectory":
    64  			user.HomeDir = strutil.ReadField(
    65  				strings.TrimSpace(strutil.ReadField(line, 1, false, ":")),
    66  				0, false, " ",
    67  			)
    68  		case "UserShell":
    69  			user.Shell = strings.TrimSpace(strutil.ReadField(line, 1, false, ":"))
    70  		}
    71  
    72  		if err != nil {
    73  			return nil, fmt.Errorf("Can't parse field %s value: %v", field, err)
    74  		}
    75  	}
    76  
    77  	user.RealUID = user.UID
    78  	user.RealGID = user.GID
    79  
    80  	return user, nil
    81  }
    82  
    83  // getGroupInfo returns group info by name
    84  func getGroupInfo(name string) (*Group, error) {
    85  	cmd := exec.Command("dscl", ".", "-read", "/Groups/"+name, "PrimaryGroupID")
    86  
    87  	out, err := cmd.Output()
    88  
    89  	if err != nil || len(out) == 0 {
    90  		return nil, fmt.Errorf("Group with name %s does not exist", name)
    91  	}
    92  
    93  	group := &Group{Name: name}
    94  	data := string(out)
    95  
    96  	group.GID, err = strconv.Atoi(strings.TrimSpace(strutil.ReadField(data, 1, false, ":")))
    97  
    98  	if err != nil {
    99  		return nil, fmt.Errorf("Can't parse PrimaryGroupID field value: %v", err)
   100  	}
   101  
   102  	return group, nil
   103  }