in emr-user-role-mapper-application/src/main/java/com/amazon/aws/emr/common/system/impl/JniBasedPrincipalResolver.java [50:98]
protected List<String> getLinuxGroups(String username) {
List<String> groups = new ArrayList<>();
log.debug("Finding groups for user: {}", username);
passwd passwdEntry = linux.getpwnam(username);
if (passwdEntry == null) {
log.error("Couldn't fetch record from password database for user: {}", username);
return groups;
}
int gid = passwdEntry.pw_gid();
log.debug("Got group id: {} for username: {}", gid, username);
int[] numGroups = new int[] { MAX_NUM_GROUPS_FETCH };
int[] allGroupIds = new int[MAX_NUM_GROUPS_FETCH];
/* If the number of groups of which user is a member is less than or equal
* to numGroups, then the value numGroups is returned.
*
* If the user is a member of more than numGroups groups, then
* getgrouplist() returns -1. In this case, the value returned in
* numGroups can be used to resize the buffer passed to a further call
* getgrouplist().
*/
int getGroupsExitCode = linux.getgrouplist(username, gid, allGroupIds, numGroups);
if (getGroupsExitCode == -1) {
log.warn("Some groups may not be fetched, {} has more than {} groups", username, MAX_NUM_GROUPS_FETCH);
}
/* nGroups[0] is always set to actual number of groups a user is part of.
* To avoid spending too much time/ putting memory pressure, we will only
* fetch minimum of {numGroups[0], MAX_NUM_GROUPS_FETCH}.
* As a follow up, we can make this limit configurable.
*/
int numGroupsToFetch = Math.min(numGroups[0], MAX_NUM_GROUPS_FETCH);
log.debug("Retrieving {} groups for username: {}", numGroupsToFetch, username);
for (int i = 0; i < numGroupsToFetch; i++) {
group grp = linux.getgrgid(allGroupIds[i]);
if (grp == null || grp.gr_name() == null) {
log.debug("No group entry found for gid: {} username: {}", allGroupIds[i], username);
continue;
}
groups.add(grp.gr_name().getString());
}
return groups;
}