Skip to content

Commit 4abb993

Browse files
committed
RANGER-4745: Enhance handling of subAccess authorization in Ranger HDFS plugin
1 parent 2d875da commit 4abb993

File tree

2 files changed

+90
-5
lines changed

2 files changed

+90
-5
lines changed

agents-common/src/main/java/org/apache/ranger/authorization/hadoop/constants/RangerHadoopConstants.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ public class RangerHadoopConstants {
2424
public static final String RANGER_OPTIMIZE_SUBACCESS_AUTHORIZATION_PROP = "ranger.optimize-subaccess-authorization" ;
2525
public static final boolean RANGER_ADD_HDFS_PERMISSION_DEFAULT = false;
2626
public static final boolean RANGER_OPTIMIZE_SUBACCESS_AUTHORIZATION_DEFAULT = false ;
27+
28+
public static final String RANGER_USE_LEGACY_SUBACCESS_AUTHORIZATION_PROP = "ranger.plugin.hdfs.use.legacy.subaccess.authorization";
29+
public static final boolean RANGER_USE_LEGACY_SUBACCESS_AUTHORIZATION_DEFAULT = true;
30+
2731
public static final String READ_ACCCESS_TYPE = "read";
2832
public static final String WRITE_ACCCESS_TYPE = "write";
2933
public static final String EXECUTE_ACCCESS_TYPE = "execute";

hdfs-agent/src/main/java/org/apache/ranger/authorization/hadoop/RangerHdfsAuthorizer.java

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ public void start() {
116116
LOG.info(RangerHadoopConstants.RANGER_OPTIMIZE_SUBACCESS_AUTHORIZATION_PROP + " is enabled");
117117
}
118118

119+
LOG.info("Legacy way of authorizing sub-access requests will " + (plugin.isUseLegacySubAccessAuthorization() ? "" : "not ") + "be used");
120+
119121
access2ActionListMapper.put(FsAction.NONE, new HashSet<String>());
120122
access2ActionListMapper.put(FsAction.ALL, Sets.newHashSet(READ_ACCCESS_TYPE, WRITE_ACCCESS_TYPE, EXECUTE_ACCCESS_TYPE));
121123
access2ActionListMapper.put(FsAction.READ, Sets.newHashSet(READ_ACCCESS_TYPE));
@@ -219,10 +221,14 @@ public RangerAccessControlEnforcer(AccessControlEnforcer defaultEnforcer) {
219221
class SubAccessData {
220222
final INodeDirectory dir;
221223
final String resourcePath;
224+
final INode[] inodes;
225+
final INodeAttributes[] iNodeAttributes;
222226

223-
SubAccessData(INodeDirectory dir, String resourcePath) {
227+
SubAccessData(INodeDirectory dir, String resourcePath, INode[] inodes, INodeAttributes[] iNodeAttributes) {
224228
this.dir = dir;
225229
this.resourcePath = resourcePath;
230+
this.iNodeAttributes = iNodeAttributes;
231+
this.inodes = inodes;
226232
}
227233
}
228234

@@ -429,7 +435,7 @@ private void checkRangerPermission(String fsOwner, String superGroup, UserGroupI
429435
if(authzStatus == AuthzStatus.ALLOW && subAccess != null && inode != null && inode.isDirectory()) {
430436
Stack<SubAccessData> directories = new Stack<>();
431437

432-
for(directories.push(new SubAccessData(inode.asDirectory(), resourcePath)); !directories.isEmpty(); ) {
438+
for(directories.push(new SubAccessData(inode.asDirectory(), resourcePath, inodes, inodeAttrs)); !directories.isEmpty(); ) {
433439
SubAccessData data = directories.pop();
434440
ReadOnlyList<INode> cList = data.dir.getChildrenList(snapshotId);
435441

@@ -438,7 +444,75 @@ private void checkRangerPermission(String fsOwner, String superGroup, UserGroupI
438444

439445
authzStatus = isAccessAllowed(data.dir, dirAttribs, data.resourcePath, subAccess, context);
440446

441-
if(authzStatus != AuthzStatus.ALLOW) {
447+
INodeDirectory dirINode;
448+
int dirAncestorIndex;
449+
INodeAttributes[] dirINodeAttrs;
450+
INode[] dirINodes;
451+
INode dirAncestor;
452+
INode dirParent;
453+
byte[][] dirComponents;
454+
455+
if (data.dir.equals(inode)) {
456+
dirINode = inode.asDirectory();
457+
dirINodeAttrs = inodeAttrs;
458+
dirINodes = inodes;
459+
dirAncestorIndex = ancestorIndex;
460+
dirAncestor = ancestor;
461+
dirParent = parent;
462+
dirComponents = pathByNameArr;
463+
} else {
464+
INodeAttributes[] curINodeAttributes;
465+
INode[] curINodes;
466+
467+
dirINode = data.dir;
468+
curINodeAttributes = data.iNodeAttributes;
469+
curINodes = data.inodes;
470+
int idx;
471+
472+
dirINodes = new INode[curINodes.length + 1];
473+
for (idx = 0; idx < curINodes.length; idx++) {
474+
dirINodes[idx] = curINodes[idx];
475+
}
476+
dirINodes[idx] = dirINode;
477+
478+
dirINodeAttrs = new INodeAttributes[curINodeAttributes.length + 1];
479+
for (idx = 0; idx < curINodeAttributes.length; idx++) {
480+
dirINodeAttrs[idx] = curINodeAttributes[idx];
481+
}
482+
dirINodeAttrs[idx] = dirAttribs;
483+
484+
for (dirAncestorIndex = dirINodes.length - 1; dirAncestorIndex >= 0 && dirINodes[dirAncestorIndex] == null; dirAncestorIndex--)
485+
;
486+
487+
dirAncestor = dirINodes.length > dirAncestorIndex && dirAncestorIndex >= 0 ? dirINodes[dirAncestorIndex] : null;
488+
dirParent = dirINodes.length > 1 ? dirINodes[dirINodes.length - 2] : null;
489+
490+
dirComponents = dirINode.getPathComponents();
491+
}
492+
493+
if (authzStatus == AuthzStatus.NOT_DETERMINED && !rangerPlugin.isUseLegacySubAccessAuthorization()) {
494+
if (LOG.isDebugEnabled()) {
495+
if (data.dir.equals(inode)) {
496+
LOG.debug("Top level directory being processed for default authorizer call, [" + data.resourcePath + "]");
497+
} else {
498+
LOG.debug("Sub directory being processed for default authorizer call, [" + data.resourcePath + "]");
499+
}
500+
LOG.debug("Calling default authorizer for hierarchy/subaccess with the following parameters");
501+
LOG.debug("fsOwner=" + fsOwner + "; superGroup=" + superGroup + ", inodesCount=" + (dirINodes != null ? dirINodes.length : 0)
502+
+ ", snapshotId=" + snapshotId + ", user=" + (ugi != null ? ugi.getShortUserName() : null) + ", provided-path=" + data.resourcePath + ", ancestorIndex=" + dirAncestorIndex
503+
+ ", doCheckOwner=" + doCheckOwner + ", ancestorAccess=null" + ", parentAccess=null"
504+
+ ", access=null" + ", subAccess=null" + ", ignoreEmptyDir=" + ignoreEmptyDir + ", operationName=" + operationName
505+
+ ", callerContext=null");
506+
}
507+
authzStatus = checkDefaultEnforcer(fsOwner, superGroup, ugi, dirINodeAttrs, dirINodes,
508+
dirComponents, snapshotId, data.resourcePath, dirAncestorIndex, doCheckOwner,
509+
null, null, null, null, ignoreEmptyDir,
510+
dirAncestor, dirParent, dirINode, context);
511+
if (LOG.isDebugEnabled()) {
512+
LOG.debug("Default authorizer call returned : [" + authzStatus + "]");
513+
}
514+
}
515+
if (authzStatus != AuthzStatus.ALLOW) {
442516
break;
443517
}
444518

@@ -454,9 +528,9 @@ private void checkRangerPermission(String fsOwner, String superGroup, UserGroupI
454528
for(INode child : cList) {
455529
if (child.isDirectory()) {
456530
if (data.resourcePath.endsWith(Path.SEPARATOR)) {
457-
directories.push(new SubAccessData(child.asDirectory(), data.resourcePath + child.getLocalName()));
531+
directories.push(new SubAccessData(child.asDirectory(), data.resourcePath + child.getLocalName(), dirINodes, dirINodeAttrs));
458532
} else {
459-
directories.push(new SubAccessData(child.asDirectory(), data.resourcePath + Path.SEPARATOR_CHAR + child.getLocalName()));
533+
directories.push(new SubAccessData(child.asDirectory(), data.resourcePath + Path.SEPARATOR_CHAR + child.getLocalName(), dirINodes, dirINodeAttrs));
460534
}
461535
}
462536
}
@@ -828,6 +902,7 @@ class RangerHdfsPlugin extends RangerBasePlugin {
828902
private final String randomizedWildcardPathName;
829903
private final String hadoopModuleName;
830904
private final Set<String> excludeUsers = new HashSet<>();
905+
private final boolean useLegacySubAccessAuthorization;
831906

832907
public RangerHdfsPlugin(Path addlConfigFile) {
833908
super("hdfs", "hdfs");
@@ -851,6 +926,9 @@ public RangerHdfsPlugin(Path addlConfigFile) {
851926

852927
String excludeUserList = config.get(RangerHadoopConstants.AUDITLOG_HDFS_EXCLUDE_LIST_PROP, RangerHadoopConstants.AUDITLOG_EMPTY_STRING);
853928

929+
this.useLegacySubAccessAuthorization = config.getBoolean(RangerHadoopConstants.RANGER_USE_LEGACY_SUBACCESS_AUTHORIZATION_PROP, RangerHadoopConstants.RANGER_USE_LEGACY_SUBACCESS_AUTHORIZATION_DEFAULT);
930+
931+
854932
if (excludeUserList != null && excludeUserList.trim().length() > 0) {
855933
for(String excludeUser : excludeUserList.trim().split(",")) {
856934
excludeUser = excludeUser.trim();
@@ -899,6 +977,9 @@ public String getRandomizedWildcardPathName() {
899977
}
900978
public String getHadoopModuleName() { return hadoopModuleName; }
901979
public Set<String> getExcludedUsers() { return excludeUsers; }
980+
public boolean isUseLegacySubAccessAuthorization() {
981+
return useLegacySubAccessAuthorization;
982+
}
902983
}
903984

904985
class RangerHdfsResource extends RangerAccessResourceImpl {

0 commit comments

Comments
 (0)