@@ -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
904985class RangerHdfsResource extends RangerAccessResourceImpl {
0 commit comments