This is an automated email from the ASF dual-hosted git repository.
abhi pushed a commit to branch ranger-2.5
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/ranger-2.5 by this push:
new 732b09182 RANGER-4818: Fix users with role assignments from undergoing
role reset to ROLE_USER (#320)
732b09182 is described below
commit 732b09182f42e731bc8bf91df2205abe3976843f
Author: Abhishek Kumar <[email protected]>
AuthorDate: Mon Jul 1 23:09:26 2024 -0700
RANGER-4818: Fix users with role assignments from undergoing role reset to
ROLE_USER (#320)
Following fixes are included in this change:
- role reset for users to happen only in the last page.
- intermediate page failures (REST failure) will result in usersync retry
after sync interval.
- added more context for debug messages in usersync.
- updateUsersRoles to return String instead of List.
(cherry picked from commit 48865de6fe97fea433d5e43f681160bd500e5a47)
---
.../main/java/org/apache/ranger/biz/XUserMgr.java | 27 ++++--
.../model/UsersGroupRoleAssignments.java | 7 ++
.../process/PolicyMgrUserGroupBuilder.java | 104 ++++++++++-----------
3 files changed, 73 insertions(+), 65 deletions(-)
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
index 92bb8d625..9899998f7 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
@@ -156,6 +156,7 @@ public class XUserMgr extends XUserMgrBase {
PlatformTransactionManager txManager;
static final Logger logger = LoggerFactory.getLogger(XUserMgr.class);
+ static final Set<String> roleAssignmentUpdatedUsers = new HashSet<>();
public VXUser getXUserByUserName(String userName) {
VXUser vXUser=null;
@@ -2964,27 +2965,35 @@ public class XUserMgr extends XUserMgrBase {
}
if (!vXPortalUser.getUserRoleList().contains(userRole))
{
- //Update the role of the user only if newly
computed role is different from the existing role.
if (logger.isDebugEnabled()) {
- logger.debug("Updating role for " +
userName + " to " + userRole);
+ logger.debug(String.format("Updating
role for %s to %s", userName, userRole));
}
+ //Update the role of the user only if newly
computed role is different from the existing role.
String updatedUser =
setRolesByUserName(userName, Collections.singletonList(userRole));
if (updatedUser != null) {
updatedUsers.add(updatedUser);
}
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug(String.format("Role for %s
unchanged: %s", userName, userRole));
+ }
+ }
+
+ if (ugRoleAssignments.isReset()) { // use below data
structure only when reset is true
+ roleAssignmentUpdatedUsers.add(userName);
}
}
// Reset the role of any other users that are not part of the
updated role assignments rules
- if (ugRoleAssignments.isReset()) {
- List<String> exitingNonUserRoleUsers =
daoManager.getXXPortalUser().getNonUserRoleExternalUsers();
+ if (ugRoleAssignments.isReset() &&
ugRoleAssignments.isLastPage()) {
+ List<String> externalUsersWithNonUserRole =
daoManager.getXXPortalUser().getNonUserRoleExternalUsers();
if (logger.isDebugEnabled()) {
- logger.debug("Existing non user role users = "
+ exitingNonUserRoleUsers);
+ logger.debug("Existing external users with
roles excluding ROLE_USER role: " + externalUsersWithNonUserRole);
}
- for (String userName : exitingNonUserRoleUsers) {
- if (!requestedUsers.contains(userName)) {
+ for (String userName : externalUsersWithNonUserRole) {
+ if
(!roleAssignmentUpdatedUsers.contains(userName)) {
if (logger.isDebugEnabled()) {
- logger.debug("Resetting to User
role for " + userName);
+
logger.debug(String.format("Resetting to ROLE_USER for %s", userName));
}
String updatedUser =
setRolesByUserName(userName,
Collections.singletonList(RangerConstants.ROLE_USER));
if (updatedUser != null) {
@@ -2992,8 +3001,8 @@ public class XUserMgr extends XUserMgrBase {
}
}
}
+ roleAssignmentUpdatedUsers.clear();
}
-
return updatedUsers;
}
diff --git
a/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/UsersGroupRoleAssignments.java
b/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/UsersGroupRoleAssignments.java
index b2470004c..ed59c6911 100644
---
a/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/UsersGroupRoleAssignments.java
+++
b/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/UsersGroupRoleAssignments.java
@@ -43,6 +43,13 @@ public class UsersGroupRoleAssignments {
Map<String, String> whiteListUserRoleAssignments;
boolean isReset = false;
+ boolean isLastPage = false;
+ public boolean isLastPage() {
+ return isLastPage;
+ }
+ public void setLastPage(boolean lastPage) {
+ isLastPage = lastPage;
+ }
public List<String> getUsers() {
return users;
diff --git
a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java
b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java
index ca5fea684..3d6d059f4 100644
---
a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java
+++
b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java
@@ -64,28 +64,19 @@ import org.apache.ranger.usergroupsync.UserGroupSink;
public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource
implements UserGroupSink {
private static final Logger LOG =
LoggerFactory.getLogger(PolicyMgrUserGroupBuilder.class);
-
private static final String AUTHENTICATION_TYPE =
"hadoop.security.authentication";
private static final String AUTH_KERBEROS = "kerberos";
private static final String KERBEROS_PRINCIPAL =
"ranger.usersync.kerberos.principal";
private static final String KERBEROS_KEYTAB =
"ranger.usersync.kerberos.keytab";
private static final String NAME_RULE =
"hadoop.security.auth_to_local";
-
public static final String PM_USER_LIST_URI =
"/service/xusers/users/"; // GET
private static final String PM_ADD_USERS_URI =
"/service/xusers/ugsync/users"; // POST
-
private static final String PM_ADD_GROUP_USER_LIST_URI =
"/service/xusers/ugsync/groupusers"; // POST
-
public static final String PM_GROUP_LIST_URI =
"/service/xusers/groups/"; // GET
private static final String PM_ADD_GROUPS_URI =
"/service/xusers/ugsync/groups/"; // POST
-
-
public static final String PM_GET_ALL_GROUP_USER_MAP_LIST_URI =
"/service/xusers/ugsync/groupusers"; // GET
-
private static final String PM_AUDIT_INFO_URI =
"/service/xusers/ugsync/auditinfo/"; // POST
-
public static final String PM_UPDATE_USERS_ROLES_URI =
"/service/xusers/users/roleassignments"; // PUT
-
private static final String PM_UPDATE_DELETED_USERS_URI =
"/service/xusers/ugsync/users/visibility"; // POST
private static final String PM_UPDATE_DELETED_GROUPS_URI =
"/service/xusers/ugsync/groups/visibility"; // POST
private static final Pattern USER_OR_GROUP_NAME_VALIDATION_REGEX =
@@ -254,7 +245,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
buildUserGroupInfo();
if (LOG.isDebugEnabled()) {
- LOG.debug("PolicyMgrUserGroupBuilderOld.init()==>
PolMgrBaseUrl : "+policyMgrBaseUrl+" KeyStore File : "+keyStoreFile+"
TrustStore File : "+trustStoreFile+ "Authentication Type :
"+authenticationType);
+
LOG.debug(String.format("PolicyMgrUserGroupBuilderOld.init()==>
policyMgrBaseUrl: %s, KeyStore File: %s, TrustStore File: %s, Authentication
Type: %s", policyMgrBaseUrl, keyStoreFile, trustStoreFile, authenticationType));
}
}
@@ -412,10 +403,10 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
private void buildUserGroupInfo() throws Throwable {
if(LOG.isDebugEnabled() && authenticationType != null &&
AUTH_KERBEROS.equalsIgnoreCase(authenticationType) &&
SecureClientLogin.isKerberosCredentialExists(principal, keytab)) {
- LOG.debug("==> Kerberos Environment : Principal is " +
principal + " and Keytab is " + keytab);
+ LOG.debug(String.format("==> Kerberos Environment :
Principal is %s and Keytab is %s", principal, keytab));
}
if (authenticationType != null &&
AUTH_KERBEROS.equalsIgnoreCase(authenticationType) &&
SecureClientLogin.isKerberosCredentialExists(principal, keytab)) {
- LOG.info("Using principal = " + principal + " and
keytab = " + keytab);
+ LOG.info(String.format("Using principal: %s and keytab:
%s", principal, keytab));
Subject sub =
SecureClientLogin.loginUserFromKeytab(principal, keytab, nameRules);
Boolean isInitDone = Subject.doAs(sub, new
PrivilegedAction<Boolean>() {
@Override
@@ -472,7 +463,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
}
}
if (LOG.isDebugEnabled()) {
- LOG.debug("RESPONSE: [" + response + "]");
+ LOG.debug(String.format("REST response from %s
: %s", PM_GROUP_LIST_URI, response));
}
GetXGroupListResponse groupList =
JsonUtils.jsonToObject(response, GetXGroupListResponse.class);
@@ -481,8 +472,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
if (groupList.getXgroupInfoList() != null) {
for (XGroupInfo g :
groupList.getXgroupInfoList()) {
if (LOG.isDebugEnabled()) {
- LOG.debug("GROUP: Id:" +
g.getId() + ", Name: " + g.getName() + ", Description: "
- +
g.getDescription());
+ LOG.debug(String.format("GROUP:
Id: %s, Name: %s, Description: %s", g.getId(), g.getName(),
g.getDescription()));
}
if(null != g.getOtherAttributes()) {
g.setOtherAttrsMap(JsonUtils.jsonToObject(g.getOtherAttributes(), Map.class));
@@ -527,7 +517,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
}
}
if (LOG.isDebugEnabled()) {
- LOG.debug("RESPONSE: [" + response + "]");
+ LOG.debug(String.format("REST response from %s
: %s", PM_USER_LIST_URI, response));
}
GetXUserListResponse userList =
JsonUtils.jsonToObject(response, GetXUserListResponse.class);
totalCount = userList.getTotalCount();
@@ -535,8 +525,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
if (userList.getXuserInfoList() != null) {
for (XUserInfo u : userList.getXuserInfoList())
{
if (LOG.isDebugEnabled()) {
- LOG.debug("USER: Id:" +
u.getId() + ", Name: " + u.getName() + ", Description: "
- +
u.getDescription());
+ LOG.debug(String.format("USER:
Id: %s, Name: %s, Description: %s", u.getId(), u.getName(),
u.getDescription()));
}
if(null != u.getOtherAttributes()) {
u.setOtherAttrsMap(JsonUtils.jsonToObject(u.getOtherAttributes(), Map.class));
@@ -574,7 +563,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
}
}
if (LOG.isDebugEnabled()) {
- LOG.debug("RESPONSE: [" + response + "]");
+ LOG.debug(String.format("REST response from %s : %s",
PM_GET_ALL_GROUP_USER_MAP_LIST_URI, response));
}
groupUsersCache = JsonUtils.jsonToObject(response, Map.class);
@@ -634,7 +623,8 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
ugRoleAssignments.setWhiteListUserRoleAssignments(whiteListUserMap);
ugRoleAssignments.setWhiteListGroupRoleAssignments(whiteListGroupMap);
ugRoleAssignments.setReset(isStartupFlag);
- if (updateRoles(ugRoleAssignments) == null) {
+ String updatedUsers = updateRoles(ugRoleAssignments);
+ if (updatedUsers == null) {
String msg = "Unable to update roles for " + allUsers;
LOG.error(msg);
throw new Exception(msg);
@@ -1031,8 +1021,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
LOG.error("Failed to addOrUpdateUsers " +
uploadedCount );
throw new Exception("Failed to
addOrUpdateUsers" + uploadedCount);
}
- LOG.info("ret = " + ret + " No. of users uploaded to
ranger admin= " + (uploadedCount>totalCount?totalCount:uploadedCount));
- }
+ LOG.info(String.format("API returned: %s, No. of users
uploaded to ranger admin = %s", ret,
(uploadedCount>totalCount?totalCount:uploadedCount))); }
if(LOG.isDebugEnabled()){
LOG.debug("<== PolicyMgrUserGroupBuilder.getUsers()");
@@ -1056,7 +1045,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
}
}
if (LOG.isDebugEnabled()) {
- LOG.debug("RESPONSE[" + response + "]");
+ LOG.debug(String.format("REST response from %s : %s",
uri, response));
}
return response;
}
@@ -1133,8 +1122,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
LOG.error("Failed to addOrUpdateGroups " +
uploadedCount );
throw new Exception("Failed to
addOrUpdateGroups " + uploadedCount);
}
- LOG.info("ret = " + ret + " No. of groups uploaded to
ranger admin= " + (uploadedCount>totalCount?totalCount:uploadedCount));
- }
+ LOG.info(String.format("API returned: %s, No. of groups
uploaded to ranger admin = %s", ret,
(uploadedCount>totalCount?totalCount:uploadedCount))); }
if(LOG.isDebugEnabled()){
LOG.debug("<== PolicyMgrUserGroupBuilder.getGroups()");
@@ -1209,15 +1197,14 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
throw new Exception("Failed to
addOrUpdateGroupUsers " + uploadedCount);
}
- LOG.info("ret = " + ret + " No. of group memberships
uploaded to ranger admin= " +
(uploadedCount>totalCount?totalCount:uploadedCount));
- }
+ LOG.info(String.format("API returned: %s, No. of group
memberships uploaded to ranger admin = %s", ret,
(uploadedCount>totalCount?totalCount:uploadedCount))); }
if(LOG.isDebugEnabled()){
LOG.debug("<==
PolicyMgrUserGroupBuilder.getGroupUsers()");
}
return ret;
}
- private List<String> updateRoles(UsersGroupRoleAssignments
ugRoleAssignments) {
+ private String updateRoles(UsersGroupRoleAssignments ugRoleAssignments)
{
if (LOG.isDebugEnabled()) {
LOG.debug("==>
PolicyMgrUserGroupBuilder.updateUserRole(" + ugRoleAssignments.getUsers() +
")");
}
@@ -1226,7 +1213,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
try {
Subject sub =
SecureClientLogin.loginUserFromKeytab(principal, keytab, nameRules);
final UsersGroupRoleAssignments result =
ugRoleAssignments;
- return Subject.doAs(sub,
(PrivilegedAction<List<String>>) () -> {
+ return Subject.doAs(sub,
(PrivilegedAction<String>) () -> {
try {
return updateUsersRoles(result);
} catch (Exception e) {
@@ -1238,16 +1225,16 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
LOG.error("Failed to Authenticate Using given
Principal and Keytab : " , e);
}
return null;
- }else{
+ } else {
return updateUsersRoles(ugRoleAssignments);
}
}
- private List<String> updateUsersRoles(UsersGroupRoleAssignments
ugRoleAssignments) {
+ private String updateUsersRoles(UsersGroupRoleAssignments
ugRoleAssignments) {
if(LOG.isDebugEnabled()){
LOG.debug("==>
PolicyMgrUserGroupBuilder.updateUserRoles(" + ugRoleAssignments.getUsers() +
")");
}
- List<String> ret = null;
+ String response = null;
try {
int totalCount = ugRoleAssignments.getUsers().size();
int uploadedCount = 0;
@@ -1263,14 +1250,17 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
pagedUgRoleAssignmentsList.setWhiteListGroupRoleAssignments(ugRoleAssignments.getWhiteListGroupRoleAssignments());
pagedUgRoleAssignmentsList.setWhiteListUserRoleAssignments(ugRoleAssignments.getWhiteListUserRoleAssignments());
pagedUgRoleAssignmentsList.setReset(ugRoleAssignments.isReset());
- String response = null;
- ClientResponse clientRes = null;
- String jsonString =
JsonUtils.objectToJson(pagedUgRoleAssignmentsList);
+ if ((uploadedCount + pageSize) >= totalCount) {
// this is the last iteration of the loop
+
pagedUgRoleAssignmentsList.setLastPage(true);
+ }
+ ClientResponse clientRes;
String url = PM_UPDATE_USERS_ROLES_URI;
if (LOG.isDebugEnabled()) {
- LOG.debug("USER role MAPPING" +
jsonString);
+ String jsonString =
JsonUtils.objectToJson(pagedUgRoleAssignmentsList);
+ LOG.debug(String.format("Paged
RoleAssignments Request to %s: %s", url, jsonString));
}
+
if (isRangerCookieEnabled) {
response =
cookieBasedUploadEntity(pagedUgRoleAssignmentsList, url);
} else {
@@ -1280,32 +1270,35 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
response =
clientRes.getEntity(String.class);
}
} catch (Throwable t) {
- LOG.error("Failed to get
response, Error is : ", t);
+ LOG.error("Failed to get
response: ", t);
}
}
+
if (LOG.isDebugEnabled()) {
- LOG.debug("RESPONSE: [" + response +
"]");
+ LOG.debug(String.format("REST response
from %s : %s", url, response));
+ }
+
+ if (response == null){
+ throw new RuntimeException("Failed to
get a REST response!");
}
- ret = JsonUtils.jsonToObject(response, new
TypeReference<ArrayList<String>>() {});
+
uploadedCount += pageSize;
}
} catch (Exception e) {
-
- LOG.warn( "ERROR: Unable to update roles for: " +
ugRoleAssignments.getUsers(), e);
+ LOG.error("Unable to update roles for: " +
ugRoleAssignments.getUsers(), e);
+ response = null;
}
if(LOG.isDebugEnabled()){
- LOG.debug("<==
PolicyMgrUserGroupBuilder.updateUserRoles(" + ret + ")");
+ LOG.debug("<==
PolicyMgrUserGroupBuilder.updateUserRoles(" + response + ")");
}
- return ret;
+ return response;
}
- private void addUserGroupAuditInfo(UgsyncAuditInfo auditInfo) throws
Throwable{
+ private void addUserGroupAuditInfo(UgsyncAuditInfo auditInfo) throws
Throwable {
if (LOG.isDebugEnabled()) {
- LOG.debug("==> PolicyMgrUserGroupBuilder.addAuditInfo("
+ auditInfo.getNoOfNewUsers() + ", " + auditInfo.getNoOfNewGroups() +
- ", " + auditInfo.getNoOfModifiedUsers()
+ ", " + auditInfo.getNoOfModifiedGroups() +
- ", " + auditInfo.getSyncSource() + ")");
+ LOG.debug(String.format("==>
PolicyMgrUserGroupBuilder.addUserGroupAuditInfo(%s, %s, %s, %s, %s)",
auditInfo.getNoOfNewUsers(), auditInfo.getNoOfNewGroups(),
auditInfo.getNoOfModifiedUsers(), auditInfo.getNoOfModifiedGroups(),
auditInfo.getSyncSource()));
}
if (authenticationType != null
@@ -1358,7 +1351,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
}
}
if (LOG.isDebugEnabled()) {
- LOG.debug("RESPONSE[" + response + "]");
+ LOG.debug(String.format("REST response from %s : %s",
PM_AUDIT_INFO_URI, response));
}
JsonUtils.jsonToObject(response, UgsyncAuditInfo.class);
@@ -1457,15 +1450,14 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
String response = null;
ClientResponse clientResp = null;
- String jsonString = JsonUtils.objectToJson(obj);
-
if ( LOG.isDebugEnabled() ) {
- LOG.debug("USER GROUP MAPPING" + jsonString);
+ String jsonString = JsonUtils.objectToJson(obj);
+ LOG.debug(String.format("User Group Mapping: %s",
jsonString));
}
- try{
+
+ try {
clientResp = ldapUgSyncClient.post(apiURL, null, obj);
- }
- catch(Throwable t){
+ } catch(Throwable t) {
LOG.error("Failed to get response, Error is : ", t);
}
if (clientResp != null) {
@@ -1812,7 +1804,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
}
}
if (LOG.isDebugEnabled()) {
- LOG.debug("RESPONSE[" + response + "]");
+ LOG.debug(String.format("REST response from %s : %s",
PM_UPDATE_DELETED_GROUPS_URI, response));
}
if (response != null) {
try {
@@ -1933,7 +1925,7 @@ public class PolicyMgrUserGroupBuilder extends
AbstractUserGroupSource implement
}
}
if (LOG.isDebugEnabled()) {
- LOG.debug("RESPONSE[" + response + "]");
+ LOG.debug(String.format("REST response from %s : %s",
PM_UPDATE_DELETED_USERS_URI, response));
}
if (response != null) {
try {