Skip to content

Commit 4875314

Browse files
ramackriramk
andauthored
RANGER-5627: Support configuration-based super users and super groups in Ranger Admin (#1013)
Co-authored-by: ramk <ramk@cloudera.com>
1 parent c8648ec commit 4875314

26 files changed

Lines changed: 1622 additions & 155 deletions

security-admin/scripts/ranger-admin-site-template.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,4 +248,14 @@
248248
<name>ranger.ldap.ad.url</name>
249249
<value></value>
250250
</property>
251+
<property>
252+
<name>ranger.admin.super.users</name>
253+
<value></value>
254+
<description>Comma-separated list of users granted full Ranger administrative privileges at login (system admin and key admin capabilities), independent of database roles. Empty or absent disables config-based super users.</description>
255+
</property>
256+
<property>
257+
<name>ranger.admin.super.groups</name>
258+
<value></value>
259+
<description>Comma-separated list of groups whose members are granted full Ranger administrative privileges at login (system admin and key admin capabilities), independent of database roles. Empty or absent disables config-based super groups.</description>
260+
</property>
251261
</configuration>

security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.apache.ranger.common.RESTErrorUtil;
4646
import org.apache.ranger.common.RangerCommonEnums;
4747
import org.apache.ranger.common.RangerConstants;
48+
import org.apache.ranger.common.RangerSuperUserConfig;
4849
import org.apache.ranger.common.StringUtil;
4950
import org.apache.ranger.common.UserSessionBase;
5051
import org.apache.ranger.db.RangerDaoManager;
@@ -95,6 +96,10 @@ public class RangerBizUtil {
9596
@Autowired
9697
UserMgr userMgr;
9798

99+
/** Used for config super-user group lookup in {@link #isUserRangerAdmin(String)}. */
100+
@Autowired
101+
XUserMgr xUserMgr;
102+
98103
@Autowired
99104
XUserService xUserService;
100105

@@ -1338,21 +1343,26 @@ public void hasKMSPermissions(String objType, String implClassName) {
13381343
+ objType, MessageEnums.OPER_NO_PERMISSION);
13391344
}
13401345

1341-
if (session.isKeyAdmin() && !EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(implClassName)) {
1342-
throw restErrorUtil.createRESTException("KeyAdmin can create/update/delete only KMS " + objType,
1343-
MessageEnums.OPER_NO_PERMISSION);
1344-
}
1346+
if (!session.isSuperUser()) {
1347+
boolean isKmsServiceType = EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(implClassName);
13451348

1346-
// TODO: As of now we are allowing SYS_ADMIN to create/update/read/delete all the
1347-
// services including KMS
1349+
if (session.isKeyAdmin() && !isKmsServiceType) {
1350+
throw restErrorUtil.createRESTException("KeyAdmin can create/update/delete only KMS " + objType,
1351+
MessageEnums.OPER_NO_PERMISSION);
1352+
}
13481353

1349-
if ("Service-Def".equalsIgnoreCase(objType) && session.isUserAdmin() && EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(implClassName)) {
1350-
throw restErrorUtil.createRESTException("System Admin cannot create/update/delete KMS " + objType,
1351-
MessageEnums.OPER_NO_PERMISSION);
1354+
if (session.isUserAdmin() && isKmsServiceType && "Service-Def".equalsIgnoreCase(objType)) {
1355+
throw restErrorUtil.createRESTException("System Admin cannot create/update/delete KMS " + objType,
1356+
MessageEnums.OPER_NO_PERMISSION);
1357+
}
13521358
}
13531359
}
13541360

13551361
public boolean checkUserAccessible(VXUser vXUser) {
1362+
if (isSuperUser()) {
1363+
return true;
1364+
}
1365+
13561366
boolean isAccessible = true;
13571367
Collection<String> roleList = userMgr.getRolesByLoginId(vXUser
13581368
.getName());
@@ -1417,6 +1427,30 @@ public boolean isUserAllowedForGrantRevoke(RangerService rangerService, String u
14171427
}
14181428

14191429
public boolean isUserRangerAdmin(String username) {
1430+
if (StringUtils.isBlank(username)) {
1431+
return false;
1432+
}
1433+
1434+
UserSessionBase userSession = ContextUtil.getCurrentUserSession();
1435+
1436+
if (userSession != null && username.equalsIgnoreCase(userSession.getLoginId()) && userSession.isUserAdmin()) {
1437+
return true;
1438+
}
1439+
1440+
final boolean configSuperUser;
1441+
1442+
if (RangerSuperUserConfig.isSuperUser(username)) {
1443+
configSuperUser = true;
1444+
} else if (RangerSuperUserConfig.isSuperGroupsConfigured() && xUserMgr != null) {
1445+
configSuperUser = RangerSuperUserConfig.isSuperUser(username, xUserMgr.getGroupsForUser(username));
1446+
} else {
1447+
configSuperUser = false;
1448+
}
1449+
1450+
if (configSuperUser) {
1451+
return true;
1452+
}
1453+
14201454
boolean isAdmin = false;
14211455
try {
14221456
VXUser vxUser = xUserService.getXUserByUserName(username);
@@ -1428,6 +1462,12 @@ public boolean isUserRangerAdmin(String username) {
14281462
return isAdmin;
14291463
}
14301464

1465+
public boolean isSuperUser() {
1466+
UserSessionBase currentUserSession = ContextUtil.getCurrentUserSession();
1467+
1468+
return currentUserSession != null && currentUserSession.isSuperUser();
1469+
}
1470+
14311471
public boolean isUserServiceAdmin(RangerService rangerService, String userName) {
14321472
boolean ret = isUserInConfigParameter(rangerService, ServiceDBStore.SERVICE_ADMIN_USERS, userName);
14331473

security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.apache.ranger.common.ContextUtil;
3434
import org.apache.ranger.common.MessageEnums;
3535
import org.apache.ranger.common.RESTErrorUtil;
36-
import org.apache.ranger.common.RangerConstants;
3736
import org.apache.ranger.common.RangerRoleCache;
3837
import org.apache.ranger.common.UserSessionBase;
3938
import org.apache.ranger.common.db.RangerTransactionSynchronizationAdapter;
@@ -315,25 +314,29 @@ public RangerRoleList getRolesForUser(SearchFilter filter, RangerRoleList ranger
315314
List<RangerRole> roles;
316315
UserSessionBase userSession = ContextUtil.getCurrentUserSession();
317316

318-
if (userSession != null && userSession.getUserRoleList().size() == 1
319-
&& userSession.getUserRoleList().contains(RangerConstants.ROLE_USER)
317+
if (userSession != null && userSession.isSingleRoleUserSession()
320318
&& userSession.getLoginId() != null) {
321319
VXUser loggedInVXUser = xUserService.getXUserByUserName(userSession.getLoginId());
322-
List<XXRole> xxRoles = daoMgr.getXXRole().findByUserId(loggedInVXUser.getId());
323320

324-
roles = new ArrayList<>();
321+
if (loggedInVXUser != null) {
322+
List<XXRole> xxRoles = daoMgr.getXXRole().findByUserId(loggedInVXUser.getId());
325323

326-
if (CollectionUtils.isNotEmpty(xxRoles)) {
327-
for (XXRole xxRole : xxRoles) {
328-
roles.add(roleService.read(xxRole.getId()));
324+
roles = new ArrayList<>();
325+
326+
if (CollectionUtils.isNotEmpty(xxRoles)) {
327+
for (XXRole xxRole : xxRoles) {
328+
roles.add(roleService.read(xxRole.getId()));
329+
}
329330
}
330-
}
331331

332-
if (predicateUtil != null && !filter.isEmpty()) {
333-
List<RangerRole> copy = new ArrayList<>(roles);
332+
if (predicateUtil != null && !filter.isEmpty()) {
333+
List<RangerRole> copy = new ArrayList<>(roles);
334334

335-
predicateUtil.applyFilter(copy, filter);
336-
roles = copy;
335+
predicateUtil.applyFilter(copy, filter);
336+
roles = copy;
337+
}
338+
} else {
339+
roles = getRoles(filter);
337340
}
338341
} else {
339342
roles = getRoles(filter);

security-admin/src/main/java/org/apache/ranger/biz/SessionMgr.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.apache.ranger.common.RESTErrorUtil;
4242
import org.apache.ranger.common.RangerCommonEnums;
4343
import org.apache.ranger.common.RangerConstants;
44+
import org.apache.ranger.common.RangerSuperUserConfig;
4445
import org.apache.ranger.common.SearchCriteria;
4546
import org.apache.ranger.common.StringUtil;
4647
import org.apache.ranger.common.UserSessionBase;
@@ -234,7 +235,12 @@ public void resetUserModulePermission(UserSessionBase userSession) {
234235

235236
XXUser xUser = daoManager.getXXUser().findByUserName(userSession.getLoginId());
236237
if (xUser != null) {
237-
List<String> permissionList = daoManager.getXXModuleDef().findAccessibleModulesByUserId(userSession.getUserId(), xUser.getId());
238+
List<String> permissionList;
239+
if (userSession.isUserAdmin() || userSession.isKeyAdmin()) {
240+
permissionList = daoManager.getXXModuleDef().getAllModuleNames();
241+
} else {
242+
permissionList = daoManager.getXXModuleDef().findAccessibleModulesByUserId(userSession.getUserId(), xUser.getId());
243+
}
238244
CopyOnWriteArraySet<String> userPermissions = new CopyOnWriteArraySet<String>(permissionList);
239245

240246
UserSessionBase.RangerUserPermission rangerUserPermission = userSession.getRangerUserPermission();
@@ -307,9 +313,47 @@ private void setUserRoles(UserSessionBase userSession) {
307313
userSession.setUserAdmin(false);
308314
}
309315

316+
applyConfigSuperUserSessionFlags(userSession);
317+
318+
if (userSession.isSuperUser()) {
319+
strRoleList = RangerSuperUserConfig.mergeConfigSuperUserRoles(strRoleList, true);
320+
}
321+
310322
userSession.setUserRoleList(strRoleList);
311323
}
312324

325+
/**
326+
* Applies config super-user session flag ({@code superUser}) when login matches
327+
* {@code ranger.admin.super.users} / super.groups.
328+
*/
329+
private void applyConfigSuperUserSessionFlags(final UserSessionBase userSession) {
330+
if (userSession == null) {
331+
return;
332+
}
333+
334+
String loginId = userSession.getLoginId();
335+
final boolean isSuperUser;
336+
337+
if (StringUtils.isBlank(loginId)) {
338+
isSuperUser = false;
339+
} else if (!RangerSuperUserConfig.isEnabled()) {
340+
isSuperUser = false;
341+
} else if (RangerSuperUserConfig.isSuperUser(loginId)) {
342+
isSuperUser = true;
343+
} else if (RangerSuperUserConfig.isSuperGroupsConfigured() && xUserMgr != null) {
344+
isSuperUser = RangerSuperUserConfig.isSuperUser(loginId, xUserMgr.getGroupsForUser(loginId));
345+
} else {
346+
isSuperUser = false;
347+
}
348+
349+
if (isSuperUser) {
350+
userSession.setSuperUser(true);
351+
logger.info("Granted full admin privileges via config for user {}", loginId);
352+
} else {
353+
userSession.setSuperUser(false);
354+
}
355+
}
356+
313357
public XXAuthSession processFailureLogin(int authStatus, int authType,
314358
String loginId, String remoteAddr, String sessionId, String userAgent) {
315359
XXAuthSession gjAuthSession = new XXAuthSession();

security-admin/src/main/java/org/apache/ranger/biz/UserMgr.java

Lines changed: 72 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@
4242
import org.apache.ranger.common.RESTErrorUtil;
4343
import org.apache.ranger.common.RangerCommonEnums;
4444
import org.apache.ranger.common.RangerConstants;
45+
import org.apache.ranger.common.RangerSuperUserConfig;
4546
import org.apache.ranger.common.SearchCriteria;
4647
import org.apache.ranger.common.SearchUtil;
4748
import org.apache.ranger.common.StringUtil;
4849
import org.apache.ranger.common.UserSessionBase;
4950
import org.apache.ranger.db.RangerDaoManager;
5051
import org.apache.ranger.entity.XXGroupPermission;
52+
import org.apache.ranger.entity.XXModuleDef;
5153
import org.apache.ranger.entity.XXPortalUser;
5254
import org.apache.ranger.entity.XXPortalUserRole;
5355
import org.apache.ranger.entity.XXTrxLogV2;
@@ -575,11 +577,16 @@ public VXPortalUser mapXXPortalUserToVXPortalUser(XXPortalUser user,
575577
|| sess.getXXPortalUser().getId().equals(user.getId())) {
576578
if (userRoleList == null) {
577579
userRoleList = new ArrayList<String>();
578-
List<XXPortalUserRole> gjUserRoleList = daoManager
579-
.getXXPortalUserRole().findByParentId(user.getId());
580580

581-
for (XXPortalUserRole userRole : gjUserRoleList) {
582-
userRoleList.add(userRole.getUserRole());
581+
if (sess.isSuperUser()) {
582+
userRoleList.addAll(RangerSuperUserConfig.getConfigSuperUserProfileRoles());
583+
} else {
584+
List<XXPortalUserRole> gjUserRoleList = daoManager
585+
.getXXPortalUserRole().findByParentId(user.getId());
586+
587+
for (XXPortalUserRole userRole : gjUserRoleList) {
588+
userRoleList.add(userRole.getUserRole());
589+
}
583590
}
584591
}
585592

@@ -638,6 +645,9 @@ protected void gjUserToUserProfile(XXPortalUser user, VXPortalUser userProfile)
638645
userProfile.setGroupPermissions(groupPermissions);
639646
userProfile.setUserPermList(vxUserPermissions);
640647
}
648+
649+
applyConfigSuperUserProfileOverrides(userProfile, sess, user);
650+
641651
userProfile.setFirstName(user.getFirstName());
642652
userProfile.setLastName(user.getLastName());
643653
userProfile.setPublicScreenName(user.getPublicScreenName());
@@ -1313,9 +1323,67 @@ public Collection<String> getRolesByLoginId(String loginId) {
13131323
if(roleList==null || roleList.size()==0){
13141324
return DEFAULT_ROLE_LIST;
13151325
}
1326+
1327+
if (!RangerSuperUserConfig.isEnabled()) {
1328+
return roleList;
1329+
}
1330+
1331+
final boolean configSuperUser;
1332+
1333+
if (RangerSuperUserConfig.isSuperUser(loginId)) {
1334+
configSuperUser = true;
1335+
} else if (RangerSuperUserConfig.isSuperGroupsConfigured() && xUserMgr != null) {
1336+
configSuperUser = RangerSuperUserConfig.isSuperUser(loginId, xUserMgr.getGroupsForUser(loginId));
1337+
} else {
1338+
configSuperUser = false;
1339+
}
1340+
1341+
if (configSuperUser) {
1342+
return RangerSuperUserConfig.mergeConfigSuperUserRoles(roleList, false);
1343+
}
1344+
13161345
return roleList;
13171346
}
13181347

1348+
/**
1349+
* For config super users viewing their own profile, expose effective
1350+
* admin roles and modules to the UI.
1351+
*/
1352+
private void applyConfigSuperUserProfileOverrides(final VXPortalUser userProfile, final UserSessionBase sess, final XXPortalUser user) {
1353+
if (sess == null || userProfile == null || user == null || !sess.isSuperUser()) {
1354+
return;
1355+
}
1356+
1357+
if (sess.getXXPortalUser() == null || !sess.getXXPortalUser().getId().equals(user.getId())) {
1358+
return;
1359+
}
1360+
1361+
List<String> effectiveRoles = RangerSuperUserConfig.getConfigSuperUserProfileRoles();
1362+
1363+
userProfile.setUserRoleList(effectiveRoles);
1364+
1365+
List<XXModuleDef> moduleDefs = daoManager.getXXModuleDef().getAll();
1366+
List<VXUserPermission> effectiveModules = new ArrayList<VXUserPermission>();
1367+
1368+
if (CollectionUtils.isNotEmpty(moduleDefs)) {
1369+
XXUser xUser = daoManager.getXXUser().findByPortalUserId(user.getId());
1370+
Long xUserId = xUser != null ? xUser.getId() : null;
1371+
1372+
for (XXModuleDef moduleDef : moduleDefs) {
1373+
VXUserPermission vxUserPermission = new VXUserPermission();
1374+
1375+
vxUserPermission.setModuleId(moduleDef.getId());
1376+
vxUserPermission.setModuleName(moduleDef.getModule());
1377+
vxUserPermission.setUserId(xUserId);
1378+
vxUserPermission.setIsAllowed(RangerCommonEnums.IS_ALLOWED);
1379+
1380+
effectiveModules.add(vxUserPermission);
1381+
}
1382+
}
1383+
1384+
userProfile.setUserPermList(effectiveModules);
1385+
}
1386+
13191387
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
13201388
public XXPortalUser updateOldUserName(String userLoginId,String newUserName, String currentPassword) {
13211389
if (userLoginId == null || newUserName == null

0 commit comments

Comments
 (0)