1
2
3
4
5 package oshi.util;
6
7 import static oshi.util.Memoizer.memoize;
8
9 import com.sun.jna.Platform;
10
11 import java.util.List;
12 import java.util.Map;
13 import java.util.concurrent.ConcurrentHashMap;
14 import java.util.concurrent.TimeUnit;
15 import java.util.function.Supplier;
16
17 import oshi.annotation.concurrent.ThreadSafe;
18
19
20
21
22
23 @ThreadSafe
24 public final class UserGroupInfo {
25
26
27
28 private static final Supplier<Map<String, String>> USERS_ID_MAP = memoize(UserGroupInfo::getUserMap,
29 TimeUnit.MINUTES.toNanos(5));
30 private static final Supplier<Map<String, String>> GROUPS_ID_MAP = memoize(UserGroupInfo::getGroupMap,
31 TimeUnit.MINUTES.toNanos(5));
32
33 private static final boolean ELEVATED = 0 == ParseUtil.parseIntOrDefault(ExecutingCommand.getFirstAnswer("id -u"),
34 -1);
35
36 private UserGroupInfo() {
37 }
38
39
40
41
42
43
44
45 public static boolean isElevated() {
46 return ELEVATED;
47 }
48
49
50
51
52
53
54
55
56
57 public static String getUser(String userId) {
58
59 return USERS_ID_MAP.get().getOrDefault(userId, getentPasswd(userId));
60 }
61
62
63
64
65
66
67
68
69 public static String getGroupName(String groupId) {
70
71 return GROUPS_ID_MAP.get().getOrDefault(groupId, getentGroup(groupId));
72 }
73
74 private static Map<String, String> getUserMap() {
75 return parsePasswd(FileUtil.readFile("/etc/passwd"));
76 }
77
78 private static String getentPasswd(String userId) {
79 if (Platform.isAIX()) {
80 return Constants.UNKNOWN;
81 }
82 Map<String, String> newUsers = parsePasswd(ExecutingCommand.runNative("getent passwd " + userId));
83
84 USERS_ID_MAP.get().putAll(newUsers);
85 return newUsers.getOrDefault(userId, Constants.UNKNOWN);
86 }
87
88 private static Map<String, String> parsePasswd(List<String> passwd) {
89 Map<String, String> userMap = new ConcurrentHashMap<>();
90
91 for (String entry : passwd) {
92 String[] split = entry.split(":");
93 if (split.length > 2) {
94 String userName = split[0];
95 String uid = split[2];
96
97
98 userMap.putIfAbsent(uid, userName);
99 }
100 }
101 return userMap;
102 }
103
104 private static Map<String, String> getGroupMap() {
105 return parseGroup(FileUtil.readFile("/etc/group"));
106 }
107
108 private static String getentGroup(String groupId) {
109 if (Platform.isAIX()) {
110 return Constants.UNKNOWN;
111 }
112 Map<String, String> newGroups = parseGroup(ExecutingCommand.runNative("getent group " + groupId));
113
114 GROUPS_ID_MAP.get().putAll(newGroups);
115 return newGroups.getOrDefault(groupId, Constants.UNKNOWN);
116 }
117
118 private static Map<String, String> parseGroup(List<String> group) {
119 Map<String, String> groupMap = new ConcurrentHashMap<>();
120
121 for (String entry : group) {
122 String[] split = entry.split(":");
123 if (split.length > 2) {
124 String groupName = split[0];
125 String gid = split[2];
126 groupMap.putIfAbsent(gid, groupName);
127 }
128 }
129 return groupMap;
130 }
131 }