From 2b801282c3fe6f3e23e81dd69dc86e9a938397cd Mon Sep 17 00:00:00 2001 From: Selvamohan Neethiraj Date: Wed, 1 Apr 2026 00:37:12 -0400 Subject: [PATCH 1/2] RANGER-5534: added validation logic for username and groupname for usersync process --- .../config/UserGroupSyncConfig.java | 35 +++++++++++++++++++ .../process/UnixUserGroupBuilder.java | 31 ++++++++++++++++ .../conf.dist/ranger-ugsync-default.xml | 16 +++++++++ 3 files changed, 82 insertions(+) diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java index 08ca725000..e371e28ebb 100644 --- a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java +++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java @@ -200,6 +200,16 @@ public class UserGroupSyncConfig { private static final String SSL_KEYSTORE_PATH_PASSWORD_ALIAS = "usersync.ssl.key.password"; private static final String SSL_TRUSTSTORE_PATH_PASSWORD_ALIAS = "usersync.ssl.truststore.password"; + private static final String UGSYNC_USERNAME_VALIDATION_REGEX_PROPERTY_NAME = "ranger.usersync.username.validation.regEx"; + private static final String UGSYNC_GROUPNAME_VALIDATION_REGEX_PROPERTY_NAME = "ranger.usersync.groupname.validation.regEx"; + private static final String UGSYNC_USERNAME_VALIDATE_PROPERTY_NAME = "ranger.usersync.username.validation.enabled"; + private static final String UGSYNC_GROUPNAME_VALIDATE_PROPERTY_NAME = "ranger.usersync.groupname.validation.enabled"; + + private static final String DEFAULT_REGEX_USERNAME_VALIDATOR = "^[a-z_][a-z0-9_-]{0,31}$" ; + private static final String DEFAULT_REGEX_GROUPNAME_VALIDATOR = "^[a-z][a-z0-9-]{0,30}$" ; + private static final boolean DEFAULT_USERNAME_VALIDATE_ENABLED = true ; + private static final boolean DEFAULT_GROUPNAME_VALIDATE_ENABLED = true ; + private static volatile UserGroupSyncConfig me; private final Properties prop = new Properties(); private Configuration userGroupConfig; @@ -1438,4 +1448,29 @@ private int getIntProperty(Properties prop, String key, int defaultValue) { return ret; } + + public boolean isUserNameValidateEnabled() { + boolean ret = DEFAULT_USERNAME_VALIDATE_ENABLED ; + String validate = prop.getProperty(UGSYNC_USERNAME_VALIDATE_PROPERTY_NAME) ; + if (validate != null) { + ret = Boolean.parseBoolean(validate); + } + return ret; + } + public boolean isGroupNameValidateEnabled() { + boolean ret = DEFAULT_GROUPNAME_VALIDATE_ENABLED ; + String validate = prop.getProperty(UGSYNC_GROUPNAME_VALIDATE_PROPERTY_NAME) ; + if (validate != null) { + ret = Boolean.parseBoolean(validate); + } + return ret; + } + + public String getUserNameValidateRegEx() { + return prop.getProperty(UGSYNC_USERNAME_VALIDATION_REGEX_PROPERTY_NAME,DEFAULT_REGEX_USERNAME_VALIDATOR) ; + } + + public String getGroupNameValidateRegEx() { + return prop.getProperty(UGSYNC_GROUPNAME_VALIDATION_REGEX_PROPERTY_NAME,DEFAULT_REGEX_GROUPNAME_VALIDATOR) ; + } } 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 2a4929b839..b1393bf7a4 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 @@ -19,6 +19,7 @@ package org.apache.ranger.unixusersync.process; +import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hadoop.thirdparty.com.google.common.collect.HashBasedTable; import org.apache.hadoop.thirdparty.com.google.common.collect.Table; @@ -85,6 +86,10 @@ public class UnixUserGroupBuilder implements UserGroupSource { private UnixSyncSourceInfo unixSyncSourceInfo; private boolean isStartupFlag; private boolean computeDeletes; + private String regExUserNameValidator; + private String regExGroupNameValidator; + private boolean validateUserName; + private boolean validateGroupName; Set allGroups = new HashSet<>(); @@ -96,6 +101,11 @@ public UnixUserGroupBuilder() { unixGroupFile = config.getUnixGroupFile(); timeout = config.getUpdateMillisMin(); enumerateGroupMembers = config.isGroupEnumerateEnabled(); + validateUserName = config.isUserNameValidateEnabled(); ; + validateGroupName = config.isGroupNameValidateEnabled() ; + regExUserNameValidator = config.getUserNameValidateRegEx() ; + regExGroupNameValidator = config.getGroupNameValidateRegEx(); ; + LOG.debug("Minimum UserId: {}, minimum GroupId: {}", minimumUserId, minimumGroupId); } @@ -330,6 +340,13 @@ private void buildUnixUserList(String command) throws Throwable { continue; } + if (validateUserName) { + if (!isValidUserName(userName)) { + LOG.warn("Ignoring Unix Username: [{}]: failed to confirm to validation-pattern: [{}]", userName, regExUserNameValidator); + continue; + } + } + int numUserId; try { @@ -459,6 +476,13 @@ private void parseMembers(String line) { return; } + if (validateGroupName) { + if (!isValidGroupName(groupName)) { + LOG.warn("Ignoring Unix GroupName: [{}]: failed to confirm to validation-pattern: [{}]", groupName, regExGroupNameValidator); + return; + } + } + groupId2groupNameMap.put(groupId, groupName); Map groupAttrMap = new HashMap<>(); @@ -592,4 +616,11 @@ private void buildUnixGroupList(String allGroupsCmd, String groupCmd, boolean us LOG.debug("Done adding extra groups"); } } + private boolean isValidUserName(String aUserName) { + return (aUserName != null && aUserName.matches(regExUserNameValidator)) ; + } + + private boolean isValidGroupName(String aGroupName) { + return (aGroupName != null && aGroupName.matches(regExGroupNameValidator)) ; + } } diff --git a/unixauthservice/conf.dist/ranger-ugsync-default.xml b/unixauthservice/conf.dist/ranger-ugsync-default.xml index 9cedc99e5d..257e8419ca 100644 --- a/unixauthservice/conf.dist/ranger-ugsync-default.xml +++ b/unixauthservice/conf.dist/ranger-ugsync-default.xml @@ -73,4 +73,20 @@ ranger.usersync.dest.ranger.session.cookie.name RANGERADMINSESSIONID + + ranger.usersync.username.validation.enabled + true + + + ranger.usersync.username.validation.regEx + ^[a-z_][a-z0-9_-]{0,31}$ + + + ranger.usersync.groupname.validation.enabled + true + + + ranger.usersync.groupname.validation.regEx + ^[a-z][a-z0-9-]{0,30}$ + From a8b548fafeff1b1b7c6db812d028eb94e0264425 Mon Sep 17 00:00:00 2001 From: Selvamohan Neethiraj Date: Wed, 1 Apr 2026 13:00:28 -0400 Subject: [PATCH 2/2] RANGER-5534: replaced the regEx for user and group validations with more generic regEx(s) that supports unicode based username and groupname --- .../ranger/unixusersync/config/UserGroupSyncConfig.java | 4 ++-- .../ranger/unixusersync/process/UnixUserGroupBuilder.java | 7 +++---- unixauthservice/conf.dist/ranger-ugsync-default.xml | 6 ++++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java index e371e28ebb..0e97de34bb 100644 --- a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java +++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java @@ -205,8 +205,8 @@ public class UserGroupSyncConfig { private static final String UGSYNC_USERNAME_VALIDATE_PROPERTY_NAME = "ranger.usersync.username.validation.enabled"; private static final String UGSYNC_GROUPNAME_VALIDATE_PROPERTY_NAME = "ranger.usersync.groupname.validation.enabled"; - private static final String DEFAULT_REGEX_USERNAME_VALIDATOR = "^[a-z_][a-z0-9_-]{0,31}$" ; - private static final String DEFAULT_REGEX_GROUPNAME_VALIDATOR = "^[a-z][a-z0-9-]{0,30}$" ; + private static final String DEFAULT_REGEX_USERNAME_VALIDATOR = "^[\\p{L}\\p{Mn}\\p{Nd}\\._-]{3,64}$" ; + private static final String DEFAULT_REGEX_GROUPNAME_VALIDATOR = "^[\\p{L}\\p{N}._\\-\\s]{1,256}$" ; private static final boolean DEFAULT_USERNAME_VALIDATE_ENABLED = true ; private static final boolean DEFAULT_GROUPNAME_VALIDATE_ENABLED = true ; 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 b1393bf7a4..c0b5ac1619 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 @@ -19,7 +19,6 @@ package org.apache.ranger.unixusersync.process; -import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hadoop.thirdparty.com.google.common.collect.HashBasedTable; import org.apache.hadoop.thirdparty.com.google.common.collect.Table; @@ -552,13 +551,13 @@ private void buildUnixGroupList(String allGroupsCmd, String groupCmd, boolean us String command; - if (useGid) { + if (useGid) { //Linux will use this section of code command = String.format(groupCmd, group.getKey()); - } else { + } else { // Mac will use this section of code command = String.format(groupCmd, group.getValue()); } - String[] cmd = new String[] {"bash", "-c", command + " " + group.getKey()}; + String[] cmd = new String[] {"bash", "-c", command }; if (LOG.isDebugEnabled()) { LOG.debug("Executing: {}", Arrays.toString(cmd)); diff --git a/unixauthservice/conf.dist/ranger-ugsync-default.xml b/unixauthservice/conf.dist/ranger-ugsync-default.xml index 257e8419ca..5fdf4d9883 100644 --- a/unixauthservice/conf.dist/ranger-ugsync-default.xml +++ b/unixauthservice/conf.dist/ranger-ugsync-default.xml @@ -79,7 +79,8 @@ ranger.usersync.username.validation.regEx - ^[a-z_][a-z0-9_-]{0,31}$ + + ^[\p{L}\p{Mn}\p{Nd}\._-]{3,64}$ ranger.usersync.groupname.validation.enabled @@ -87,6 +88,7 @@ ranger.usersync.groupname.validation.regEx - ^[a-z][a-z0-9-]{0,30}$ + + ^[\p{L}\p{N}._\-\s]{1,256}$