sysuser.go 2.41 KB
Newer Older
liming6's avatar
liming6 committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package utils

import (
	"os"
	"os/exec"
	"strconv"
	"strings"
)

/*
获取Linux系统上所有用户的信息,如果系统安装了nis,还要解析nis的用户
*/

const (
	NISClient = "ypbind"
	NISCat    = "ypcat"
)

// detectNis 探测系统是否为Nis的客户端,即解析是否存在ypbind命令,且ypbind命令在运行
func detectNis() (bool, error) {
	haveCmd, _ := DetectCmd(NISClient)
	if haveCmd == false {
		return false, nil
	}
	ps, err := GetProcessByName(NISClient)
	if err != nil {
		return false, err
	}
	if len(ps) > 0 {
		return true, nil
	}
	return false, nil
}

// GetNisUsers 获取Nis中的所有用户信息
func GetNisUsers() ([]SysUser, error) {
	haveCmd, cmdPath := DetectCmd(NISCat)
	if !haveCmd {
		return make([]SysUser, 0), nil
	}
	output, err := exec.Command(cmdPath, "passwd").Output()
	if err != nil {
		return nil, err
	}
	return parseSysUser(string(output))
}

type SysUser struct {
	Name         string
	Uid          int
	Gid          int
	IsSystemUser bool
	HomeDir      string
	Shell        string
	GECOS        string // 用户信息
}

// parseSysUser 从字符串中解析系统用户信息
func parseSysUser(str string) ([]SysUser, error) {
	sysUsers := make([]SysUser, 0)
	lines := strings.Split(strings.Trim(str, "\n"), "\n")
	if len(lines) == 0 {
		return sysUsers, nil
	}
	for _, line := range lines {
		fields := strings.Split(line, ":")
		if len(fields) != 7 {
			continue
		}
		user := SysUser{}
		user.Name = strings.TrimSpace(fields[0])
		uid, err := strconv.Atoi(strings.TrimSpace(fields[2]))
		if err != nil {
			return nil, err
		}
		user.Uid = uid
		if user.Uid >= 1000 {
			user.IsSystemUser = false
		} else {
			user.IsSystemUser = true
		}
		gid, err := strconv.Atoi(strings.TrimSpace(fields[3]))
		if err != nil {
			return nil, err
		}
		user.Gid = gid
		user.GECOS = fields[4]
		user.HomeDir = strings.TrimSpace(fields[5])
		user.Shell = strings.TrimSpace(fields[6])
		sysUsers = append(sysUsers, user)
	}
	return sysUsers, nil
}

// GetSysUsers 获取系统上所有的用户
func GetSysUsers() ([]SysUser, error) {
	detect, err := detectNis()
	if err != nil {
		return nil, err
	}
	result := make([]SysUser, 0)
	if detect {
		u, _ := GetNisUsers()
		result = append(result, u...)
	}
	u, err := os.ReadFile("/etc/passwd")
	if err != nil {
		return result, nil
	}
	su, err := parseSysUser(string(u))
	if err != nil {
		return result, nil
	}
	result = append(result, su...)
	return result, nil
}