HADOOP-14935. Azure: POSIX permissions are taking effect in access() method even when authorization is enabled.

Contributed by Santhosh G Nayak
This commit is contained in:
Steve Loughran 2017-10-16 16:01:47 +01:00
parent 20575ececb
commit 9fcc3a1fc8
3 changed files with 254 additions and 90 deletions

View File

@ -71,9 +71,11 @@ import org.apache.hadoop.fs.azure.metrics.AzureFileSystemMetricsSystem;
import org.apache.hadoop.fs.azure.security.Constants; import org.apache.hadoop.fs.azure.security.Constants;
import org.apache.hadoop.fs.azure.security.RemoteWasbDelegationTokenManager; import org.apache.hadoop.fs.azure.security.RemoteWasbDelegationTokenManager;
import org.apache.hadoop.fs.azure.security.WasbDelegationTokenManager; import org.apache.hadoop.fs.azure.security.WasbDelegationTokenManager;
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.fs.permission.PermissionStatus; import org.apache.hadoop.fs.permission.PermissionStatus;
import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.token.Token; import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticatedURL; import org.apache.hadoop.security.token.delegation.web.DelegationTokenAuthenticatedURL;
@ -2650,22 +2652,6 @@ public class NativeAzureFileSystem extends FileSystem {
public FileStatus getFileStatus(Path f) throws FileNotFoundException, IOException { public FileStatus getFileStatus(Path f) throws FileNotFoundException, IOException {
LOG.debug("Getting the file status for {}", f.toString()); LOG.debug("Getting the file status for {}", f.toString());
// Capture the absolute path and the path to key.
Path absolutePath = makeAbsolute(f);
if (!isRenamePendingFile(absolutePath)) {
Path ancestor = getAncestor(absolutePath);
if (ancestor.equals(absolutePath) && !ancestor.equals(new Path("/"))) {
performAuthCheck(ancestor.getParent(), WasbAuthorizationOperations.READ,
"getFileStatus", absolutePath);
}
else {
performAuthCheck(ancestor, WasbAuthorizationOperations.READ,
"getFileStatus", absolutePath);
}
}
return getFileStatusInternal(f); return getFileStatusInternal(f);
} }
@ -2693,7 +2679,15 @@ public class NativeAzureFileSystem extends FileSystem {
} }
} }
protected FileStatus getFileStatusInternal(Path f) throws FileNotFoundException, IOException { /**
* Inner implementation of {@link #getFileStatus(Path)}.
* Return a file status object that represents the path.
* @param f The path we want information from
* @return a FileStatus object
* @throws FileNotFoundException when the path does not exist
* @throws IOException Other failure
*/
private FileStatus getFileStatusInternal(Path f) throws FileNotFoundException, IOException {
Path absolutePath = makeAbsolute(f); Path absolutePath = makeAbsolute(f);
String key = pathToKey(absolutePath); String key = pathToKey(absolutePath);
@ -3707,6 +3701,41 @@ public class NativeAzureFileSystem extends FileSystem {
} }
} }
@Override
public void access(Path path, FsAction mode) throws IOException {
if (azureAuthorization && authorizer != null) {
try {
// Required to check the existence of the path.
getFileStatus(path);
switch (mode) {
case READ:
case READ_EXECUTE:
performAuthCheck(path, WasbAuthorizationOperations.READ, "access", path);
break;
case WRITE:
case WRITE_EXECUTE:
performAuthCheck(path, WasbAuthorizationOperations.WRITE, "access",
path);
break;
case READ_WRITE:
case ALL:
performAuthCheck(path, WasbAuthorizationOperations.READ, "access", path);
performAuthCheck(path, WasbAuthorizationOperations.WRITE, "access",
path);
break;
case EXECUTE:
case NONE:
default:
break;
}
} catch (WasbAuthorizationException wae){
throw new AccessControlException(wae);
}
} else {
super.access(path, mode);
}
}
/** /**
* A handler that defines what to do with blobs whose upload was * A handler that defines what to do with blobs whose upload was
* interrupted. * interrupted.

View File

@ -34,6 +34,7 @@ public final class Constants {
*/ */
public static final String AZURE_ENABLE_SPNEGO_TOKEN_CACHE = public static final String AZURE_ENABLE_SPNEGO_TOKEN_CACHE =
"fs.azure.enable.spnego.token.cache"; "fs.azure.enable.spnego.token.cache";
/** /**
* Parameter to be used for impersonation. * Parameter to be used for impersonation.
*/ */

View File

@ -24,6 +24,7 @@ import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataInputStream;
@ -31,9 +32,12 @@ import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.contract.ContractTestUtils; import org.apache.hadoop.fs.contract.ContractTestUtils;
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.test.GenericTestUtils; import org.apache.hadoop.test.GenericTestUtils;
import org.apache.hadoop.test.LambdaTestUtils;
import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.util.StringUtils;
import org.junit.Assume; import org.junit.Assume;
@ -145,7 +149,6 @@ public class TestNativeAzureFileSystemAuthorization
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner("/", READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -171,7 +174,6 @@ public class TestNativeAzureFileSystemAuthorization
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.getParent().toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -199,7 +201,6 @@ public class TestNativeAzureFileSystemAuthorization
setExpectedFailureMessage("create", testPath); setExpectedFailureMessage("create", testPath);
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.getParent().toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -225,7 +226,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.toString(), WRITE, true); authorizer.addAuthRuleForOwner(testPath.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -331,7 +331,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
/* for rename */ /* for rename */
authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -362,7 +361,6 @@ public class TestNativeAzureFileSystemAuthorization
/* to create parent dir */ /* to create parent dir */
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, false); authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, false);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -395,8 +393,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); /* to create parent dir */ authorizer.addAuthRuleForOwner("/", WRITE, true); /* to create parent dir */
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentSrcDir.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(parentDstDir.toString(), WRITE, false); authorizer.addAuthRuleForOwner(parentDstDir.toString(), WRITE, false);
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), READ, true);
authorizer.addAuthRuleForOwner(parentDstDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -426,8 +422,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); /* to create parent dirs */ authorizer.addAuthRuleForOwner("/", WRITE, true); /* to create parent dirs */
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentSrcDir.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(parentDstDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentDstDir.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), READ, true);
authorizer.addAuthRuleForOwner(parentDstDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -605,9 +599,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentSrcDir.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(parentDstDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentDstDir.toString(), WRITE, true);
/* Required for asserPathExists calls */ /* Required for asserPathExists calls */
authorizer.addAuthRuleForOwner("/", READ, true);
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), READ, true);
authorizer.addAuthRuleForOwner(parentDstDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -648,9 +639,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), authorizer.addAuthRuleForOwner(parentSrcDir.toString(),
WRITE, true); WRITE, true);
/* Required for asserPathExists calls */ /* Required for asserPathExists calls */
authorizer.addAuthRuleForOwner("/", READ, true);
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), READ, true);
authorizer.addAuthRuleForOwner(parentDstDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -672,10 +660,6 @@ public class TestNativeAzureFileSystemAuthorization
WRITE, getCurrentUserShortName(), true); WRITE, getCurrentUserShortName(), true);
authorizer.addAuthRule(parentDstDir.toString(), authorizer.addAuthRule(parentDstDir.toString(),
WRITE, getCurrentUserShortName(), true); WRITE, getCurrentUserShortName(), true);
authorizer.addAuthRule(parentSrcDir.toString(),
READ, getCurrentUserShortName(), true);
authorizer.addAuthRule(parentDstDir.toString(),
READ, getCurrentUserShortName(), true);
try { try {
fs.rename(srcPath, dstPath); fs.rename(srcPath, dstPath);
@ -711,9 +695,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), authorizer.addAuthRuleForOwner(parentSrcDir.toString(),
WRITE, true); WRITE, true);
/* Required for asserPathExists calls */ /* Required for asserPathExists calls */
authorizer.addAuthRuleForOwner("/", READ, true);
authorizer.addAuthRuleForOwner(parentSrcDir.toString(), READ, true);
authorizer.addAuthRuleForOwner(parentDstDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -735,10 +716,6 @@ public class TestNativeAzureFileSystemAuthorization
WRITE, getCurrentUserShortName(), true); WRITE, getCurrentUserShortName(), true);
authorizer.addAuthRule(parentDstDir.toString(), authorizer.addAuthRule(parentDstDir.toString(),
WRITE, getCurrentUserShortName(), true); WRITE, getCurrentUserShortName(), true);
authorizer.addAuthRule(parentSrcDir.toString(),
READ, getCurrentUserShortName(), true);
authorizer.addAuthRule(parentDstDir.toString(),
READ, getCurrentUserShortName(), true);
// should return false since srcPath does not exist. // should return false since srcPath does not exist.
assertRenameOutcome(fs, srcPath, dstPath, false); assertRenameOutcome(fs, srcPath, dstPath, false);
assertPathDoesNotExist(fs, "destPath exists", dstPath); assertPathDoesNotExist(fs, "destPath exists", dstPath);
@ -840,7 +817,6 @@ public class TestNativeAzureFileSystemAuthorization
Path testPath = new Path(parentDir, "test.dat"); Path testPath = new Path(parentDir, "test.dat");
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
fs.create(testPath); fs.create(testPath);
@ -865,7 +841,6 @@ public class TestNativeAzureFileSystemAuthorization
setExpectedFailureMessage("delete", testPath); setExpectedFailureMessage("delete", testPath);
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
fs.create(testPath); fs.create(testPath);
@ -875,7 +850,6 @@ public class TestNativeAzureFileSystemAuthorization
/* Remove permissions for delete to force failure */ /* Remove permissions for delete to force failure */
authorizer.deleteAllAuthRules(); authorizer.deleteAllAuthRules();
authorizer.addAuthRuleForOwner("/", WRITE, false); authorizer.addAuthRuleForOwner("/", WRITE, false);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
fs.delete(testPath, false); fs.delete(testPath, false);
@ -884,7 +858,6 @@ public class TestNativeAzureFileSystemAuthorization
/* Restore permissions to force a successful delete */ /* Restore permissions to force a successful delete */
authorizer.deleteAllAuthRules(); authorizer.deleteAllAuthRules();
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner("/", READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
fs.delete(testPath, false); fs.delete(testPath, false);
@ -905,8 +878,6 @@ public class TestNativeAzureFileSystemAuthorization
Path testPath = new Path(childPath, "test.dat"); Path testPath = new Path(childPath, "test.dat");
authorizer.addAuthRuleForOwner("/", WRITE, true); // for create and delete authorizer.addAuthRuleForOwner("/", WRITE, true); // for create and delete
authorizer.addAuthRuleForOwner(childPath.toString(), READ, true);
authorizer.addAuthRuleForOwner("/", READ, true);
authorizer.addAuthRuleForOwner("/testDeleteIntermediateFolder*", authorizer.addAuthRuleForOwner("/testDeleteIntermediateFolder*",
WRITE, true); // for recursive delete WRITE, true); // for recursive delete
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
@ -939,8 +910,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner("/testDeleteAuthCheckFailureLeavesFilesUndeleted*", authorizer.addAuthRuleForOwner("/testDeleteAuthCheckFailureLeavesFilesUndeleted*",
WRITE, true); WRITE, true);
authorizer.addAuthRuleForOwner(childPath1.toString(), READ, true);
authorizer.addAuthRuleForOwner(childPath2.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -955,9 +924,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(childPath2.toString(), WRITE, true); authorizer.addAuthRuleForOwner(childPath2.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(childPath1.toString(), WRITE, false); authorizer.addAuthRuleForOwner(childPath1.toString(), WRITE, false);
authorizer.addAuthRuleForOwner(childPath1.toString(), READ, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
authorizer.addAuthRuleForOwner("/", READ, true);
assertFalse(fs.delete(parentDir, true)); assertFalse(fs.delete(parentDir, true));
@ -986,7 +952,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1023,7 +988,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1041,8 +1005,6 @@ public class TestNativeAzureFileSystemAuthorization
try { try {
authorizer.addAuthRule(parentDir.toString(), WRITE, authorizer.addAuthRule(parentDir.toString(), WRITE,
getCurrentUserShortName(), true); getCurrentUserShortName(), true);
authorizer.addAuthRule(parentDir.toString(), READ,
getCurrentUserShortName(), true);
fs.delete(testPath, true); fs.delete(testPath, true);
return null; return null;
} }
@ -1075,8 +1037,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner("/testRecursiveDeleteSucceedsWithStickybit*", authorizer.addAuthRuleForOwner("/testRecursiveDeleteSucceedsWithStickybit*",
WRITE, true); WRITE, true);
authorizer.addAuthRuleForOwner(childDir.toString(), READ, true);
authorizer.addAuthRuleForOwner("/", READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1113,8 +1073,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner("/testRecursiveDeleteFailsWithStickybit*", authorizer.addAuthRuleForOwner("/testRecursiveDeleteFailsWithStickybit*",
WRITE, true); WRITE, true);
authorizer.addAuthRuleForOwner(childDir.toString(), READ, true);
authorizer.addAuthRuleForOwner("/", READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1170,7 +1128,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner( authorizer.addAuthRuleForOwner(
"/testDeleteSucceedsForOnlyFilesOwnedByUserWithStickybitSet*", "/testDeleteSucceedsForOnlyFilesOwnedByUserWithStickybitSet*",
WRITE, true); WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1185,11 +1142,8 @@ public class TestNativeAzureFileSystemAuthorization
@Override @Override
public Void run() throws Exception { public Void run() throws Exception {
authorizer.addAuthRule("/", WRITE, getCurrentUserShortName(), true); authorizer.addAuthRule("/", WRITE, getCurrentUserShortName(), true);
authorizer.addAuthRule(parentDir.toString(), READ, getCurrentUserShortName(), true);
authorizer.addAuthRule(testFolderPath.toString(), READ, getCurrentUserShortName(), true);
authorizer.addAuthRule("/testDeleteSucceedsForOnlyFilesOwnedByUserWithStickybitSet*", authorizer.addAuthRule("/testDeleteSucceedsForOnlyFilesOwnedByUserWithStickybitSet*",
WRITE, getCurrentUserShortName(), true); WRITE, getCurrentUserShortName(), true);
authorizer.addAuthRule("/", READ, getCurrentUserShortName(), true);
fs.create(testFolderPath); // the folder will have owner as dummyuser fs.create(testFolderPath); // the folder will have owner as dummyuser
ContractTestUtils.assertPathExists(fs, "folder was not created", testFolderPath); ContractTestUtils.assertPathExists(fs, "folder was not created", testFolderPath);
@ -1228,8 +1182,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner( authorizer.addAuthRuleForOwner(
"/testDeleteSucceedsForParentDirectoryOwnerUserWithStickybit*", "/testDeleteSucceedsForParentDirectoryOwnerUserWithStickybit*",
WRITE, true); WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
authorizer.addAuthRuleForOwner("/", READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1244,7 +1196,6 @@ public class TestNativeAzureFileSystemAuthorization
@Override @Override
public Void run() throws Exception { public Void run() throws Exception {
authorizer.addAuthRule(parentDir.toString(), WRITE, getCurrentUserShortName(), true); authorizer.addAuthRule(parentDir.toString(), WRITE, getCurrentUserShortName(), true);
authorizer.addAuthRule(parentDir.toString(), READ, getCurrentUserShortName(), true);
fs.create(testFilePath); fs.create(testFilePath);
ContractTestUtils.assertPathExists(fs, "file was not created", testFilePath); ContractTestUtils.assertPathExists(fs, "file was not created", testFilePath);
@ -1282,10 +1233,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner("/testDeleteScenarioForRoot*", authorizer.addAuthRuleForOwner("/testDeleteScenarioForRoot*",
WRITE, true); WRITE, true);
authorizer.addAuthRuleForOwner(childPath1.toString(), READ, true);
authorizer.addAuthRuleForOwner(childPath2.toString(), READ, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
authorizer.addAuthRuleForOwner("/", READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1329,7 +1276,6 @@ public class TestNativeAzureFileSystemAuthorization
Path testPath = new Path("/testMkdirsAccessCheckPositive/1/2/3"); Path testPath = new Path("/testMkdirsAccessCheckPositive/1/2/3");
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.getParent().toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1352,7 +1298,6 @@ public class TestNativeAzureFileSystemAuthorization
Path testPath = new Path("/testMkdirsWithExistingHierarchyCheckPositive1"); Path testPath = new Path("/testMkdirsWithExistingHierarchyCheckPositive1");
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.getParent().toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1386,10 +1331,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner(childPath1.toString(), authorizer.addAuthRuleForOwner(childPath1.toString(),
WRITE, true); WRITE, true);
authorizer.addAuthRuleForOwner(childPath1.getParent().toString(), READ, true);
authorizer.addAuthRuleForOwner(testPath.getParent().toString(), READ, true);
authorizer.addAuthRuleForOwner(childPath3.getParent().toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1464,8 +1405,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true); authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true);
// additional rule used for assertPathExists // additional rule used for assertPathExists
authorizer.addAuthRuleForOwner(parentDir.toString(), READ, true);
authorizer.addAuthRuleForOwner("/", READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1543,7 +1482,6 @@ public class TestNativeAzureFileSystemAuthorization
Path testPath = new Path("/testSetOwnerNegative"); Path testPath = new Path("/testSetOwnerNegative");
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner("/", READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
final String owner; final String owner;
@ -1582,7 +1520,6 @@ public class TestNativeAzureFileSystemAuthorization
Path testPath = new Path("/testSetOwnerPositive"); Path testPath = new Path("/testSetOwnerPositive");
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.getParent().toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
String newOwner = "user2"; String newOwner = "user2";
@ -1626,7 +1563,6 @@ public class TestNativeAzureFileSystemAuthorization
Configuration conf = fs.getConf(); Configuration conf = fs.getConf();
authorizer.init(conf); authorizer.init(conf);
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.getParent().toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
final String newOwner = "newowner"; final String newOwner = "newowner";
@ -1670,7 +1606,6 @@ public class TestNativeAzureFileSystemAuthorization
Configuration conf = fs.getConf(); Configuration conf = fs.getConf();
authorizer.init(conf); authorizer.init(conf);
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.getParent().toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
UserGroupInformation user = UserGroupInformation.createUserForTesting( UserGroupInformation user = UserGroupInformation.createUserForTesting(
@ -1714,8 +1649,6 @@ public class TestNativeAzureFileSystemAuthorization
authorizer.addAuthRuleForOwner("/", WRITE, true); authorizer.addAuthRuleForOwner("/", WRITE, true);
/* Remove nextline after fixing createInternal from FolderRenamePending */ /* Remove nextline after fixing createInternal from FolderRenamePending */
authorizer.addAuthRuleForOwner(testPath.toString(), WRITE, true); authorizer.addAuthRuleForOwner(testPath.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(srcPath.getParent().toString(), READ, true);
authorizer.addAuthRuleForOwner(dstFilePath.getParent().toString(), READ, true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
try { try {
@ -1833,6 +1766,197 @@ public class TestNativeAzureFileSystemAuthorization
} }
/**
* Test access when requested permissions match the existing permissions.
*/
@Test
public void testAccessWhenPermissionsMatchForAllAndReadWrite() throws Throwable {
Configuration conf = fs.getConf();
fs.setConf(conf);
final Path testPath = new Path("/testAccessWhenPermissionsMatchForAllAndReadWrite");
// For All and Read-Write FsAction.
authorizer.init(conf);
authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.toString(), WRITE, true);
authorizer.addAuthRuleForOwner(testPath.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer);
try {
fs.mkdirs(testPath);
assertPathExists(fs, "test path does not exist", testPath);
fs.access(testPath, FsAction.ALL);
fs.access(testPath, FsAction.READ_WRITE);
} finally {
recursiveDelete(testPath);
}
}
/**
* Test access when Write and Write-Execute match the existing permissions.
* @throws Throwable
*/
@Test
public void testAccessWhenPermissionsMatchForWriteAndWriteExecute() throws Throwable {
Configuration conf = fs.getConf();
fs.setConf(conf);
final Path testPath = new Path("/testAccessWhenPermissionsMatchForWriteAndWriteExecute");
// For Write and Write-Execute FsAction.
authorizer.init(conf);
authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.toString(), WRITE, true);
fs.updateWasbAuthorizer(authorizer);
try {
fs.mkdirs(testPath);
assertPathExists(fs, "test path does not exist", testPath);
fs.access(testPath, FsAction.WRITE);
fs.access(testPath, FsAction.WRITE_EXECUTE);
} finally {
recursiveDelete(testPath);
}
}
/**
* Test access when Read and Read-Execute match the existing permissions.
* @throws Throwable
*/
@Test
public void testAccessWhenPermissionsMatchForReadAndReadExecute() throws Throwable {
Configuration conf = fs.getConf();
fs.setConf(conf);
final Path testPath = new Path("/testAccessWhenPermissionsMatchForReadAndReadExecute");
// For Read and Read-Execute FsAction.
authorizer.init(conf);
authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer);
try {
fs.mkdirs(testPath);
assertPathExists(fs, "test path does not exist", testPath);
fs.access(testPath, FsAction.READ);
fs.access(testPath, FsAction.READ_EXECUTE);
} finally {
recursiveDelete(testPath);
}
}
/**
* Test access when Execute and None match the existing permissions.
* @throws Throwable
*/
@Test
public void testAccessWhenPermissionsMatchForExecuteAndNone() throws Throwable {
Configuration conf = fs.getConf();
fs.setConf(conf);
final Path testPath = new Path("/testAccessWhenPermissionsMatchForExecuteAndNone");
// For Execute and None FsAction.
authorizer.init(conf);
authorizer.addAuthRuleForOwner("/", WRITE, true);
fs.updateWasbAuthorizer(authorizer);
try {
fs.mkdirs(testPath);
assertPathExists(fs, "test path does not exist", testPath);
fs.access(testPath, FsAction.EXECUTE);
fs.access(testPath, FsAction.NONE);
} finally {
recursiveDelete(testPath);
}
}
/**
* Test access when requested permissions do not match existing permissions.
*/
@Test
public void testAccessWhenPermissionsDoNotMatch() throws Throwable{
Configuration conf = fs.getConf();
fs.setConf(conf);
final Path testPath = new Path("/testAccessWhenPermissionsDoNotMatch");
authorizer.init(conf);
authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(testPath.toString(), READ, true);
fs.updateWasbAuthorizer(authorizer);
try {
fs.mkdirs(testPath);
assertPathExists(fs, "test path does not exist", testPath);
assertNoAccess(testPath, FsAction.ALL);
assertNoAccess(testPath, FsAction.WRITE);
assertNoAccess(testPath, FsAction.WRITE_EXECUTE);
} finally {
recursiveDelete(testPath);
}
}
/**
* Test access when file does not exist and permissions match.
*/
@Test
public void testAccessFileDoesNotExist() throws Throwable{
expectedEx.expect(FileNotFoundException.class);
Configuration conf = fs.getConf();
fs.setConf(conf);
final Path testPath = new Path("/testAccessFileDoesNotExist");
authorizer.init(conf);
authorizer.addAuthRuleForOwner(testPath.toString(), READ, true);
authorizer.addAuthRuleForOwner(testPath.toString(), WRITE, true);
fs.updateWasbAuthorizer(authorizer);
assertPathDoesNotExist(fs, "test path exists", testPath);
fs.access(testPath, FsAction.ALL);
}
/**
* Test access when file does not exist and permissions do not match.
*/
@Test
public void testAccessFileDoesNotExistWhenNoAccessPermission() throws Throwable {
expectedEx.expect(FileNotFoundException.class);
Configuration conf = fs.getConf();
fs.setConf(conf);
final Path testPath = new Path("/testAccessFileDoesNotExistWhenNoAccessPermission");
authorizer.init(conf);
fs.updateWasbAuthorizer(authorizer);
assertPathDoesNotExist(fs, "test path exists", testPath);
fs.access(testPath, FsAction.ALL);
}
/**
* Test access for file and intermediate directory after creating
* file with intermediate directory.
*/
@Test
public void testAccessForFileAndIntermediateDirectoryCreated() throws Throwable {
Path parentDir = new Path("/testAccessDirectory");
Path intermediateDir = new Path(parentDir, "intermediateDir");
Path testPath = new Path(intermediateDir, "test.dat");
authorizer.addAuthRuleForOwner("/", WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString(), WRITE, true);
// Recursive owner Rule is to determine the permission on intermediate dirs.
authorizer.addAuthRuleForOwner(parentDir.toString()+"/*", WRITE, true);
authorizer.addAuthRuleForOwner(parentDir.toString()+"/*", READ, true);
fs.updateWasbAuthorizer(authorizer);
try {
fs.mkdirs(parentDir);
fs.create(testPath);
assertPathExists(fs, "testPath was not created", testPath);
fs.access(parentDir, FsAction.WRITE);
fs.access(parentDir, FsAction.WRITE_EXECUTE);
fs.access(intermediateDir, FsAction.ALL);
fs.access(intermediateDir, FsAction.READ_WRITE);
fs.access(testPath, FsAction.ALL);
fs.access(testPath, FsAction.READ_WRITE);
} finally {
recursiveDelete(testPath);
}
}
/** /**
* Helper method to test setPermission scenarios. This method handles both positive * Helper method to test setPermission scenarios. This method handles both positive
* and negative scenarios of setPermission tests * and negative scenarios of setPermission tests
@ -1849,7 +1973,6 @@ public class TestNativeAzureFileSystemAuthorization
final Path testPath = new Path(path); final Path testPath = new Path(path);
final FsPermission newPermission = new FsPermission(FULL_PERMISSION_WITH_STICKYBIT); final FsPermission newPermission = new FsPermission(FULL_PERMISSION_WITH_STICKYBIT);
authorizer.addAuthRule("/", WRITE, getCurrentUserShortName(), true); authorizer.addAuthRule("/", WRITE, getCurrentUserShortName(), true);
authorizer.addAuthRule("/", READ, getCurrentUserShortName(), true);
fs.updateWasbAuthorizer(authorizer); fs.updateWasbAuthorizer(authorizer);
if (chmodAllowedUsers != null && !chmodAllowedUsers.isEmpty()) { if (chmodAllowedUsers != null && !chmodAllowedUsers.isEmpty()) {
@ -1895,7 +2018,6 @@ public class TestNativeAzureFileSystemAuthorization
public Void run() throws Exception { public Void run() throws Exception {
try { try {
//READ access required for getFileStatus //READ access required for getFileStatus
authorizer.addAuthRule("/", READ, getCurrentUserShortName(), true);
fs.setPermission(testPath, newPermission); fs.setPermission(testPath, newPermission);
fail("Failing test because setPermission was expected to throw"); fail("Failing test because setPermission was expected to throw");
@ -1961,4 +2083,16 @@ public class TestNativeAzureFileSystemAuthorization
assertEquals("Wrong owner in " + status, owner, status.getOwner()); assertEquals("Wrong owner in " + status, owner, status.getOwner());
} }
private void assertNoAccess(final Path path, final FsAction action)
throws Exception {
LambdaTestUtils.intercept(AccessControlException.class,
new Callable<String>() {
@Override
public String call() throws Exception {
fs.access(path, action);
return "Access granted to " + path + " for action " + action;
}
}
);
}
} }