You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2022/07/25 18:07:00 UTC
[ranger] 25/28: RANGER-3813: Fix ConcurrentModificationException in UnixUserGroupBuilder
This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch ranger-2.4
in repository https://gitbox.apache.org/repos/asf/ranger.git
commit 9742d503c844c1dc89524f28648418cee38f40ef
Author: Abhishek Kumar <ab...@gmail.com>
AuthorDate: Tue Jun 28 20:45:59 2022 -0700
RANGER-3813: Fix ConcurrentModificationException in UnixUserGroupBuilder
Signed-off-by: pradeep <pr...@apache.org>
(cherry picked from commit c51fedfba9efb61c1ff7bf9b41f4db4b965fe1a7)
---
.../unixusersync/process/UnixUserGroupBuilder.java | 134 ++++++++-------------
1 file changed, 51 insertions(+), 83 deletions(-)
diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/UnixUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/UnixUserGroupBuilder.java
index 7653dfdbe..d6b54c30a 100644
--- a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/UnixUserGroupBuilder.java
+++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/UnixUserGroupBuilder.java
@@ -60,8 +60,7 @@ public class UnixUserGroupBuilder implements UserGroupSource {
static final String LINUX_GET_ALL_GROUPS_CMD = "getent group";
static final String LINUX_GET_GROUP_CMD = "getent group %s";
- // mainly for testing purposes
- // there might be a better way
+ // mainly for testing purposes, there might be a better way
static final String MAC_GET_ALL_USERS_CMD = "dscl . -readall /Users UniqueID PrimaryGroupID | " +
"awk 'BEGIN { OFS = \":\"; ORS=\"\\n\"; i=0;}" +
"/RecordName: / {name = $2;i = 0;}/PrimaryGroupID: / {gid = $2;}" +
@@ -107,7 +106,9 @@ public class UnixUserGroupBuilder implements UserGroupSource {
public static void main(String[] args) throws Throwable {
UnixUserGroupBuilder ugbuilder = new UnixUserGroupBuilder();
ugbuilder.init();
- ugbuilder.print();
+ if (LOG.isDebugEnabled()) {
+ ugbuilder.print();
+ }
}
public UnixUserGroupBuilder() {
@@ -185,11 +186,7 @@ public class UnixUserGroupBuilder implements UserGroupSource {
}
long TempGroupFileModifiedAt = new File(unixGroupFile).lastModified();
- if (groupFileModifiedAt != TempGroupFileModifiedAt) {
- return true;
- }
-
- return false;
+ return groupFileModifiedAt != TempGroupFileModifiedAt;
}
@@ -225,12 +222,12 @@ public class UnixUserGroupBuilder implements UserGroupSource {
private void buildUserGroupInfo() throws Throwable {
- groupId2groupNameMap = new HashMap<String, String>();
- sourceUsers = new HashMap<>();
- sourceGroups = new HashMap<>();
- sourceGroupUsers = new HashMap<>();
- groupUserTable = HashBasedTable.create();
- allGroups = new HashSet<>();
+ groupId2groupNameMap = new HashMap<>();
+ sourceUsers = new HashMap<>();
+ sourceGroups = new HashMap<>();
+ sourceGroupUsers = new HashMap<>();
+ groupUserTable = HashBasedTable.create();
+ allGroups = new HashSet<>();
if (OS.startsWith("Mac")) {
buildUnixGroupList(MAC_GET_ALL_GROUPS_CMD, MAC_GET_GROUP_CMD, false);
@@ -245,11 +242,11 @@ public class UnixUserGroupBuilder implements UserGroupSource {
Iterator<String> groupUserTableIterator = groupUserTable.rowKeySet().iterator();
while (groupUserTableIterator.hasNext()) {
- String groupName = groupUserTableIterator.next();
- Map<String,String> groupUsersMap = groupUserTable.row(groupName);
- Set<String> userSet = new HashSet<String>();
- for(String userName : groupUsersMap.keySet()){
- //String transformUserName = userNameTransform(entry.getKey());
+ String groupName = groupUserTableIterator.next();
+ Map<String, String> groupUsersMap = groupUserTable.row(groupName);
+ Set<String> userSet = new HashSet<>();
+
+ for (String userName : groupUsersMap.keySet()) {
if (sourceUsers.containsKey(userName)) {
userSet.add(userName);
}
@@ -266,23 +263,17 @@ public class UnixUserGroupBuilder implements UserGroupSource {
private void print() {
for(String user : sourceUsers.keySet()) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("USER:" + user);
- }
+ LOG.debug("USER:" + user);
Set<String> groups = groupUserTable.column(user).keySet();
- if (groups != null) {
- for(String group : groups) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("\tGROUP: " + group);
- }
- }
+ for(String group : groups) {
+ LOG.debug("\tGROUP: " + group);
}
}
}
private void buildUnixUserList(String command) throws Throwable {
BufferedReader reader = null;
- Map<String, String> userName2uid = new HashMap<String, String>();
+ Map<String, String> userName2uid = new HashMap<>();
try {
if (!useNss) {
@@ -291,14 +282,11 @@ public class UnixUserGroupBuilder implements UserGroupSource {
FileInputStream fis = new FileInputStream(file);
reader = new BufferedReader(new InputStreamReader(fis, StandardCharsets.UTF_8));
} else {
- Process process = Runtime.getRuntime().exec(
- new String[]{"bash", "-c", command});
-
+ Process process = Runtime.getRuntime().exec(new String[]{"bash", "-c", command});
reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
}
- String line = null;
-
+ String line;
while ((line = reader.readLine()) != null) {
if (line.trim().isEmpty())
continue;
@@ -312,22 +300,21 @@ public class UnixUserGroupBuilder implements UserGroupSource {
continue;
}
- String userName = null;
- String userId = null;
- String groupId = null;
+ String userName;
+ String userId;
+ String groupId;
try {
userName = tokens[0];
- userId = tokens[2];
- groupId = tokens[3];
+ userId = tokens[2];
+ groupId = tokens[3];
}
catch(ArrayIndexOutOfBoundsException aiobe) {
LOG.warn("Ignoring line - [" + line + "]: Unable to parse line for getting user information", aiobe);
continue;
}
- int numUserId = -1;
-
+ int numUserId;
try {
numUserId = Integer.parseInt(userId);
} catch (NumberFormatException nfe) {
@@ -346,7 +333,7 @@ public class UnixUserGroupBuilder implements UserGroupSource {
sourceUsers.put(userName, userAttrMap);
groupUserTable.put(groupName, userName, groupId);
} else {
- // we are ignoring the possibility that this user was present in /etc/groups.
+ // we are ignoring the possibility that this user was present in getent group.
LOG.warn("Group Name could not be found for group id: [" + groupId + "]. Skipping adding user [" + userName + "] with id [" + userId + "].");
}
} else {
@@ -365,36 +352,24 @@ public class UnixUserGroupBuilder implements UserGroupSource {
// this does a reverse check as not all users might be listed in getent passwd
if (enumerateGroupMembers) {
- String line = null;
+ String line;
+ Table<String, String, String> tempGroupUserTable = HashBasedTable.create();
if (LOG.isDebugEnabled()) {
LOG.debug("Start drill down group members");
}
for (String userName : groupUserTable.columnKeySet()) {
- // skip users we already now about
- if (sourceUsers.containsKey(userName))
+
+ if (sourceUsers.containsKey(userName))// skip users we already now about
continue;
if (LOG.isDebugEnabled()) {
LOG.debug("Enumerating user " + userName);
}
- int numUserId = -1;
- try {
- numUserId = Integer.parseInt(userName2uid.get(userName));
- } catch (NumberFormatException nfe) {
- numUserId = -1;
- }
-
- // if a user comes from an external group we might not have a uid
- if (numUserId < minimumUserId && numUserId != -1)
- continue;
-
-
// "id" is same across Linux / BSD / MacOSX
// gids are used as id might return groups with spaces, ie "domain users"
- Process process = Runtime.getRuntime().exec(
- new String[]{"bash", "-c", "id -G " + userName});
+ Process process = Runtime.getRuntime().exec(new String[]{"bash", "-c", "id -G " + userName});
try {
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
@@ -412,27 +387,26 @@ public class UnixUserGroupBuilder implements UserGroupSource {
continue;
}
- String[] gids = line.split(" ");
-
// check if all groups returned by id are visible to ranger
- //ArrayList<String> allowedGroups = new ArrayList<String>();
- for (String gid : gids) {
- int numGroupId = Integer.parseInt(gid);
- if (numGroupId < minimumGroupId)
- continue;
-
- String groupName = groupId2groupNameMap.get(gid);
- if (groupName != null) {
- groupUserTable.put(groupName, userName, gid);
- //allowedGroups.add(groupName);
+ for (String gid : line.split(" ")) {
+ if (Integer.parseInt(gid) >= minimumGroupId) {
+ String groupName = groupId2groupNameMap.get(gid);
+ if (groupName != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("New group user mapping found : " + groupName + " " + userName);
+ }
+ tempGroupUserTable.put(groupName, userName, gid);
+ }
}
}
+
Map<String, String> userAttrMap = new HashMap<>();
userAttrMap.put(UgsyncCommonConstants.ORIGINAL_NAME, userName);
userAttrMap.put(UgsyncCommonConstants.FULL_NAME, userName);
userAttrMap.put(UgsyncCommonConstants.SYNC_SOURCE, currentSyncSource);
sourceUsers.put(userName, userAttrMap);
}
+ groupUserTable.putAll(tempGroupUserTable);
if (LOG.isDebugEnabled()) {
LOG.debug("End drill down group members");
}
@@ -455,9 +429,7 @@ public class UnixUserGroupBuilder implements UserGroupSource {
if (tokens.length > 3)
groupMembers = tokens[3];
- if (groupId2groupNameMap.containsKey(groupId)) {
- groupId2groupNameMap.remove(groupId);
- }
+ groupId2groupNameMap.remove(groupId);
int numGroupId = Integer.parseInt(groupId);
if (numGroupId < minimumGroupId)
@@ -492,18 +464,14 @@ public class UnixUserGroupBuilder implements UserGroupSource {
FileInputStream fis = new FileInputStream(file);
reader = new BufferedReader(new InputStreamReader(fis, StandardCharsets.UTF_8));
} else {
- Process process = Runtime.getRuntime().exec(
- new String[]{"bash", "-c", allGroupsCmd});
+ Process process = Runtime.getRuntime().exec(new String[]{"bash", "-c", allGroupsCmd});
reader = new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
}
- String line = null;
-
+ String line;
while ((line = reader.readLine()) != null) {
- if (line.trim().isEmpty())
- continue;
-
- parseMembers(line);
+ if (!line.trim().isEmpty())
+ parseMembers(line);
}
} finally {
if (reader != null)
@@ -561,7 +529,7 @@ public class UnixUserGroupBuilder implements UserGroupSource {
}
if (config.getEnumerateGroups() != null) {
- String line = null;
+ String line;
String[] groups = config.getEnumerateGroups().split(",");
if (LOG.isDebugEnabled()) {