Skip to content

Commit 1052c17

Browse files
committed
[SPARK-24948][SHS] Delegate check access permissions to the file system
1 parent ef6c839 commit 1052c17

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

core/src/main/scala/org/apache/spark/deploy/SparkHadoopUtil.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import scala.collection.JavaConverters._
2626
import scala.collection.immutable.Map
2727
import scala.collection.mutable
2828
import scala.collection.mutable.HashMap
29+
import scala.util.Try
2930
import scala.util.control.NonFatal
3031

3132
import com.google.common.primitives.Longs
@@ -383,6 +384,10 @@ class SparkHadoopUtil extends Logging {
383384
return true
384385
}
385386

387+
// We may still be able to access the file as ACL may be enabled or spark may be an admin user
388+
if (Try(status.getPath.getFileSystem(conf).access(status.getPath, mode)).isSuccess) {
389+
return true
390+
}
386391
logDebug(s"Permission denied: user=${ugi.getShortUserName}, " +
387392
s"path=${status.getPath}:${status.getOwner}:${status.getGroup}" +
388393
s"${if (status.isDirectory) "d" else "-"}$perm")

core/src/test/scala/org/apache/spark/deploy/SparkHadoopUtilSuite.scala

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ import java.security.PrivilegedExceptionAction
2121

2222
import scala.util.Random
2323

24-
import org.apache.hadoop.fs.FileStatus
24+
import org.apache.hadoop.fs.{FileStatus, FileSystem, Path}
2525
import org.apache.hadoop.fs.permission.{FsAction, FsPermission}
26-
import org.apache.hadoop.security.UserGroupInformation
26+
import org.apache.hadoop.security.{AccessControlException, UserGroupInformation}
27+
import org.mockito
28+
import org.mockito.internal.stubbing.answers.DoesNothing
29+
import org.mockito.Mockito._
2730
import org.scalatest.Matchers
2831

2932
import org.apache.spark.SparkFunSuite
@@ -72,6 +75,14 @@ class SparkHadoopUtilSuite extends SparkFunSuite with Matchers {
7275
sparkHadoopUtil.checkAccessPermission(status, READ) should be(false)
7376
sparkHadoopUtil.checkAccessPermission(status, WRITE) should be(false)
7477

78+
status = mockedStatus(otherUser, otherGroup, READ_WRITE, READ_WRITE, NONE, true)
79+
sparkHadoopUtil.checkAccessPermission(status, READ) should be(true)
80+
sparkHadoopUtil.checkAccessPermission(status, WRITE) should be(true)
81+
82+
status = mockedStatus(otherUser, otherGroup, READ_WRITE, READ_WRITE, NONE, false)
83+
sparkHadoopUtil.checkAccessPermission(status, READ) should be(false)
84+
sparkHadoopUtil.checkAccessPermission(status, WRITE) should be(false)
85+
7586
null
7687
}
7788
})
@@ -94,4 +105,26 @@ class SparkHadoopUtilSuite extends SparkFunSuite with Matchers {
94105
group,
95106
null)
96107
}
108+
109+
private def mockedStatus(
110+
owner: String,
111+
group: String,
112+
userAction: FsAction,
113+
groupAction: FsAction,
114+
otherAction: FsAction,
115+
accessGranted: Boolean): FileStatus = {
116+
val mockedFs = mock(classOf[FileSystem])
117+
val stub = when(mockedFs.access(mockito.Matchers.any(), mockito.Matchers.any()))
118+
if (accessGranted) {
119+
stub.thenAnswer(new DoesNothing)
120+
} else {
121+
stub.thenThrow(new AccessControlException)
122+
}
123+
val mockedPath = mock(classOf[Path])
124+
when(mockedPath.getFileSystem(mockito.Matchers.any())).thenReturn(mockedFs)
125+
// This status has no access permission, here we modify only the Path it returns
126+
val mockedStatus = spy(fileStatus(owner, group, userAction, groupAction, otherAction))
127+
when(mockedStatus.getPath).thenReturn(mockedPath)
128+
mockedStatus
129+
}
97130
}

0 commit comments

Comments
 (0)