HDFS-3733. Audit logs should include WebHDFS access. Contributed by Andy Isaacson
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1379278 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
34d1e73235
commit
7d1c8d92f9
@ -698,6 +698,8 @@ Branch-2 ( Unreleased changes )
|
|||||||
|
|
||||||
HDFS-3837. Fix DataNode.recoverBlock findbugs warning. (eli)
|
HDFS-3837. Fix DataNode.recoverBlock findbugs warning. (eli)
|
||||||
|
|
||||||
|
HDFS-3733. Audit logs should include WebHDFS access. (Andy Isaacson via eli)
|
||||||
|
|
||||||
BREAKDOWN OF HDFS-3042 SUBTASKS
|
BREAKDOWN OF HDFS-3042 SUBTASKS
|
||||||
|
|
||||||
HDFS-2185. HDFS portion of ZK-based FailoverController (todd)
|
HDFS-2185. HDFS portion of ZK-based FailoverController (todd)
|
||||||
|
@ -169,6 +169,7 @@
|
|||||||
import org.apache.hadoop.hdfs.server.namenode.ha.StandbyState;
|
import org.apache.hadoop.hdfs.server.namenode.ha.StandbyState;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.metrics.FSNamesystemMBean;
|
import org.apache.hadoop.hdfs.server.namenode.metrics.FSNamesystemMBean;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.metrics.NameNodeMetrics;
|
import org.apache.hadoop.hdfs.server.namenode.metrics.NameNodeMetrics;
|
||||||
|
import org.apache.hadoop.hdfs.server.namenode.web.resources.NamenodeWebHdfsMethods;
|
||||||
import org.apache.hadoop.hdfs.server.protocol.DatanodeCommand;
|
import org.apache.hadoop.hdfs.server.protocol.DatanodeCommand;
|
||||||
import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration;
|
import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration;
|
||||||
import org.apache.hadoop.hdfs.server.protocol.HeartbeatResponse;
|
import org.apache.hadoop.hdfs.server.protocol.HeartbeatResponse;
|
||||||
@ -1071,7 +1072,7 @@ void setPermission(String src, FsPermission permission)
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"setPermission", src, null, null);
|
"setPermission", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -1100,7 +1101,7 @@ private void setPermissionInt(String src, FsPermission permission)
|
|||||||
getEditLog().logSync();
|
getEditLog().logSync();
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"setPermission", src, null, resultingStat);
|
"setPermission", src, null, resultingStat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1117,7 +1118,7 @@ void setOwner(String src, String username, String group)
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"setOwner", src, null, null);
|
"setOwner", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -1155,7 +1156,7 @@ private void setOwnerInt(String src, String username, String group)
|
|||||||
getEditLog().logSync();
|
getEditLog().logSync();
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"setOwner", src, null, resultingStat);
|
"setOwner", src, null, resultingStat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1190,7 +1191,7 @@ LocatedBlocks getBlockLocations(String src, long offset, long length,
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"open", src, null, null);
|
"open", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -1216,7 +1217,7 @@ private LocatedBlocks getBlockLocationsInt(String src, long offset, long length,
|
|||||||
offset, length, doAccessTime, needBlockToken);
|
offset, length, doAccessTime, needBlockToken);
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"open", src, null, null);
|
"open", src, null, null);
|
||||||
}
|
}
|
||||||
if (checkSafeMode && isInSafeMode()) {
|
if (checkSafeMode && isInSafeMode()) {
|
||||||
@ -1301,7 +1302,7 @@ void concat(String target, String [] srcs)
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getLoginUser(),
|
logAuditEvent(false, UserGroupInformation.getLoginUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"concat", Arrays.toString(srcs), target, null);
|
"concat", Arrays.toString(srcs), target, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -1351,7 +1352,7 @@ private void concatInt(String target, String [] srcs)
|
|||||||
getEditLog().logSync();
|
getEditLog().logSync();
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getLoginUser(),
|
logAuditEvent(UserGroupInformation.getLoginUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"concat", Arrays.toString(srcs), target, resultingStat);
|
"concat", Arrays.toString(srcs), target, resultingStat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1468,7 +1469,7 @@ void setTimes(String src, long mtime, long atime)
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"setTimes", src, null, null);
|
"setTimes", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -1495,7 +1496,7 @@ private void setTimesInt(String src, long mtime, long atime)
|
|||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
final HdfsFileStatus stat = dir.getFileInfo(src, false);
|
final HdfsFileStatus stat = dir.getFileInfo(src, false);
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"setTimes", src, null, stat);
|
"setTimes", src, null, stat);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1517,7 +1518,7 @@ void createSymlink(String target, String link,
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"createSymlink", link, target, null);
|
"createSymlink", link, target, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -1545,7 +1546,7 @@ private void createSymlinkInt(String target, String link,
|
|||||||
getEditLog().logSync();
|
getEditLog().logSync();
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"createSymlink", link, target, resultingStat);
|
"createSymlink", link, target, resultingStat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1601,7 +1602,7 @@ boolean setReplication(final String src, final short replication)
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"setReplication", src, null, null);
|
"setReplication", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -1637,7 +1638,7 @@ private boolean setReplicationInt(final String src, final short replication)
|
|||||||
getEditLog().logSync();
|
getEditLog().logSync();
|
||||||
if (isFile && auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (isFile && auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"setReplication", src, null, null);
|
"setReplication", src, null, null);
|
||||||
}
|
}
|
||||||
return isFile;
|
return isFile;
|
||||||
@ -1694,7 +1695,7 @@ void startFile(String src, PermissionStatus permissions, String holder,
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"create", src, null, null);
|
"create", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -1719,7 +1720,7 @@ private void startFileInt(String src, PermissionStatus permissions, String holde
|
|||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
final HdfsFileStatus stat = dir.getFileInfo(src, false);
|
final HdfsFileStatus stat = dir.getFileInfo(src, false);
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"create", src, null, stat);
|
"create", src, null, stat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2017,7 +2018,7 @@ LocatedBlock appendFile(String src, String holder, String clientMachine)
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"append", src, null, null);
|
"append", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -2055,7 +2056,7 @@ private LocatedBlock appendFileInt(String src, String holder, String clientMachi
|
|||||||
}
|
}
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"append", src, null, null);
|
"append", src, null, null);
|
||||||
}
|
}
|
||||||
return lb;
|
return lb;
|
||||||
@ -2521,7 +2522,7 @@ boolean renameTo(String src, String dst)
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"rename", src, dst, null);
|
"rename", src, dst, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -2550,7 +2551,7 @@ private boolean renameToInt(String src, String dst)
|
|||||||
getEditLog().logSync();
|
getEditLog().logSync();
|
||||||
if (status && auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (status && auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"rename", src, dst, resultingStat);
|
"rename", src, dst, resultingStat);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
@ -2610,7 +2611,7 @@ void renameTo(String src, String dst, Options.Rename... options)
|
|||||||
for (Rename option : options) {
|
for (Rename option : options) {
|
||||||
cmd.append(option.value()).append(" ");
|
cmd.append(option.value()).append(" ");
|
||||||
}
|
}
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(), Server.getRemoteIp(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(), getRemoteIp(),
|
||||||
cmd.toString(), src, dst, resultingStat);
|
cmd.toString(), src, dst, resultingStat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2648,7 +2649,7 @@ boolean delete(String src, boolean recursive)
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"delete", src, null, null);
|
"delete", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -2664,7 +2665,7 @@ private boolean deleteInt(String src, boolean recursive)
|
|||||||
boolean status = deleteInternal(src, recursive, true);
|
boolean status = deleteInternal(src, recursive, true);
|
||||||
if (status && auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (status && auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"delete", src, null, null);
|
"delete", src, null, null);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
@ -2802,8 +2803,11 @@ private boolean isSafeModeTrackingBlocks() {
|
|||||||
*/
|
*/
|
||||||
HdfsFileStatus getFileInfo(String src, boolean resolveLink)
|
HdfsFileStatus getFileInfo(String src, boolean resolveLink)
|
||||||
throws AccessControlException, UnresolvedLinkException,
|
throws AccessControlException, UnresolvedLinkException,
|
||||||
StandbyException {
|
StandbyException, IOException {
|
||||||
|
HdfsFileStatus stat = null;
|
||||||
|
|
||||||
readLock();
|
readLock();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
checkOperation(OperationCategory.READ);
|
checkOperation(OperationCategory.READ);
|
||||||
|
|
||||||
@ -2813,10 +2817,23 @@ HdfsFileStatus getFileInfo(String src, boolean resolveLink)
|
|||||||
if (isPermissionEnabled) {
|
if (isPermissionEnabled) {
|
||||||
checkTraverse(src);
|
checkTraverse(src);
|
||||||
}
|
}
|
||||||
return dir.getFileInfo(src, resolveLink);
|
stat = dir.getFileInfo(src, resolveLink);
|
||||||
|
} catch (AccessControlException e) {
|
||||||
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
|
getRemoteIp(),
|
||||||
|
"getfileinfo", src, null, null);
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
readUnlock();
|
readUnlock();
|
||||||
}
|
}
|
||||||
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
|
getRemoteIp(),
|
||||||
|
"getfileinfo", src, null, null);
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2829,7 +2846,7 @@ boolean mkdirs(String src, PermissionStatus permissions,
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"mkdirs", src, null, null);
|
"mkdirs", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -2854,7 +2871,7 @@ private boolean mkdirsInt(String src, PermissionStatus permissions,
|
|||||||
if (status && auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (status && auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
final HdfsFileStatus stat = dir.getFileInfo(src, false);
|
final HdfsFileStatus stat = dir.getFileInfo(src, false);
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"mkdirs", src, null, stat);
|
"mkdirs", src, null, stat);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
@ -3295,7 +3312,7 @@ DirectoryListing getListing(String src, byte[] startAfter,
|
|||||||
} catch (AccessControlException e) {
|
} catch (AccessControlException e) {
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
logAuditEvent(false, UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"listStatus", src, null, null);
|
"listStatus", src, null, null);
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
@ -3319,7 +3336,7 @@ private DirectoryListing getListingInt(String src, byte[] startAfter,
|
|||||||
}
|
}
|
||||||
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
|
||||||
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
logAuditEvent(UserGroupInformation.getCurrentUser(),
|
||||||
Server.getRemoteIp(),
|
getRemoteIp(),
|
||||||
"listStatus", src, null, null);
|
"listStatus", src, null, null);
|
||||||
}
|
}
|
||||||
dl = dir.getListing(src, startAfter, needLocation);
|
dl = dir.getListing(src, startAfter, needLocation);
|
||||||
@ -5250,7 +5267,15 @@ private AuthenticationMethod getConnectionAuthenticationMethod()
|
|||||||
* RPC call context even if the client exits.
|
* RPC call context even if the client exits.
|
||||||
*/
|
*/
|
||||||
private boolean isExternalInvocation() {
|
private boolean isExternalInvocation() {
|
||||||
return Server.isRpcInvocation();
|
return Server.isRpcInvocation() || NamenodeWebHdfsMethods.isWebHdfsInvocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static InetAddress getRemoteIp() {
|
||||||
|
InetAddress ip = Server.getRemoteIp();
|
||||||
|
if (ip != null) {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
return NamenodeWebHdfsMethods.getRemoteIp();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
@ -92,6 +93,7 @@
|
|||||||
import org.apache.hadoop.hdfs.web.resources.TokenArgumentParam;
|
import org.apache.hadoop.hdfs.web.resources.TokenArgumentParam;
|
||||||
import org.apache.hadoop.hdfs.web.resources.UriFsPathParam;
|
import org.apache.hadoop.hdfs.web.resources.UriFsPathParam;
|
||||||
import org.apache.hadoop.hdfs.web.resources.UserParam;
|
import org.apache.hadoop.hdfs.web.resources.UserParam;
|
||||||
|
import org.apache.hadoop.ipc.Server;
|
||||||
import org.apache.hadoop.net.NodeBase;
|
import org.apache.hadoop.net.NodeBase;
|
||||||
import org.apache.hadoop.security.Credentials;
|
import org.apache.hadoop.security.Credentials;
|
||||||
import org.apache.hadoop.security.SecurityUtil;
|
import org.apache.hadoop.security.SecurityUtil;
|
||||||
@ -116,9 +118,20 @@ public static String getRemoteAddress() {
|
|||||||
return REMOTE_ADDRESS.get();
|
return REMOTE_ADDRESS.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set the remote client address. */
|
public static InetAddress getRemoteIp() {
|
||||||
static void setRemoteAddress(String remoteAddress) {
|
try {
|
||||||
REMOTE_ADDRESS.set(remoteAddress);
|
return InetAddress.getByName(getRemoteAddress());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a WebHdfs request is in progress. Akin to
|
||||||
|
* {@link Server#isRpcInvocation()}.
|
||||||
|
*/
|
||||||
|
public static boolean isWebHdfsInvocation() {
|
||||||
|
return getRemoteAddress() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private @Context ServletContext context;
|
private @Context ServletContext context;
|
||||||
|
@ -61,7 +61,7 @@ public static LocatedBlocks getBlockLocations(NameNode namenode,
|
|||||||
|
|
||||||
public static HdfsFileStatus getFileInfo(NameNode namenode, String src,
|
public static HdfsFileStatus getFileInfo(NameNode namenode, String src,
|
||||||
boolean resolveLink) throws AccessControlException, UnresolvedLinkException,
|
boolean resolveLink) throws AccessControlException, UnresolvedLinkException,
|
||||||
StandbyException {
|
StandbyException, IOException {
|
||||||
return namenode.getNamesystem().getFileInfo(src, resolveLink);
|
return namenode.getNamesystem().getFileInfo(src, resolveLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,13 +32,17 @@
|
|||||||
|
|
||||||
import org.apache.commons.logging.impl.Log4JLogger;
|
import org.apache.commons.logging.impl.Log4JLogger;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
|
import org.apache.hadoop.fs.FileStatus;
|
||||||
import org.apache.hadoop.fs.FileSystem;
|
import org.apache.hadoop.fs.FileSystem;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
||||||
import org.apache.hadoop.hdfs.DFSTestUtil;
|
import org.apache.hadoop.hdfs.DFSTestUtil;
|
||||||
import org.apache.hadoop.hdfs.HdfsConfiguration;
|
import org.apache.hadoop.hdfs.HdfsConfiguration;
|
||||||
|
import org.apache.hadoop.hdfs.HftpFileSystem;
|
||||||
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
import org.apache.hadoop.hdfs.MiniDFSCluster;
|
||||||
|
import org.apache.hadoop.hdfs.web.WebHdfsTestUtil;
|
||||||
|
import org.apache.hadoop.hdfs.web.WebHdfsFileSystem;
|
||||||
import org.apache.hadoop.security.AccessControlException;
|
import org.apache.hadoop.security.AccessControlException;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.log4j.Level;
|
import org.apache.log4j.Level;
|
||||||
@ -83,6 +87,7 @@ public void setupCluster() throws Exception {
|
|||||||
final long precision = 1L;
|
final long precision = 1L;
|
||||||
conf.setLong(DFSConfigKeys.DFS_NAMENODE_ACCESSTIME_PRECISION_KEY, precision);
|
conf.setLong(DFSConfigKeys.DFS_NAMENODE_ACCESSTIME_PRECISION_KEY, precision);
|
||||||
conf.setLong(DFSConfigKeys.DFS_BLOCKREPORT_INTERVAL_MSEC_KEY, 10000L);
|
conf.setLong(DFSConfigKeys.DFS_BLOCKREPORT_INTERVAL_MSEC_KEY, 10000L);
|
||||||
|
conf.setBoolean(DFSConfigKeys.DFS_WEBHDFS_ENABLED_KEY, true);
|
||||||
util = new DFSTestUtil.Builder().setName("TestAuditAllowed").
|
util = new DFSTestUtil.Builder().setName("TestAuditAllowed").
|
||||||
setNumFiles(20).build();
|
setNumFiles(20).build();
|
||||||
cluster = new MiniDFSCluster.Builder(conf).numDataNodes(4).build();
|
cluster = new MiniDFSCluster.Builder(conf).numDataNodes(4).build();
|
||||||
@ -115,6 +120,18 @@ public void testAuditAllowed() throws Exception {
|
|||||||
assertTrue("failed to read from file", val > 0);
|
assertTrue("failed to read from file", val > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** test that allowed stat puts proper entry in audit log */
|
||||||
|
@Test
|
||||||
|
public void testAuditAllowedStat() throws Exception {
|
||||||
|
final Path file = new Path(fnames[0]);
|
||||||
|
FileSystem userfs = DFSTestUtil.getFileSystemAs(userGroupInfo, conf);
|
||||||
|
|
||||||
|
setupAuditLogs();
|
||||||
|
FileStatus st = userfs.getFileStatus(file);
|
||||||
|
verifyAuditLogs(true);
|
||||||
|
assertTrue("failed to stat file", st != null && st.isFile());
|
||||||
|
}
|
||||||
|
|
||||||
/** test that denied operation puts proper entry in audit log */
|
/** test that denied operation puts proper entry in audit log */
|
||||||
@Test
|
@Test
|
||||||
public void testAuditDenied() throws Exception {
|
public void testAuditDenied() throws Exception {
|
||||||
@ -135,6 +152,85 @@ public void testAuditDenied() throws Exception {
|
|||||||
verifyAuditLogs(false);
|
verifyAuditLogs(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** test that access via webhdfs puts proper entry in audit log */
|
||||||
|
@Test
|
||||||
|
public void testAuditWebHdfs() throws Exception {
|
||||||
|
final Path file = new Path(fnames[0]);
|
||||||
|
|
||||||
|
fs.setPermission(file, new FsPermission((short)0644));
|
||||||
|
fs.setOwner(file, "root", null);
|
||||||
|
|
||||||
|
setupAuditLogs();
|
||||||
|
|
||||||
|
WebHdfsFileSystem webfs = WebHdfsTestUtil.getWebHdfsFileSystemAs(userGroupInfo, conf);
|
||||||
|
InputStream istream = webfs.open(file);
|
||||||
|
int val = istream.read();
|
||||||
|
istream.close();
|
||||||
|
|
||||||
|
verifyAuditLogsRepeat(true, 3);
|
||||||
|
assertTrue("failed to read from file", val > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** test that stat via webhdfs puts proper entry in audit log */
|
||||||
|
@Test
|
||||||
|
public void testAuditWebHdfsStat() throws Exception {
|
||||||
|
final Path file = new Path(fnames[0]);
|
||||||
|
|
||||||
|
fs.setPermission(file, new FsPermission((short)0644));
|
||||||
|
fs.setOwner(file, "root", null);
|
||||||
|
|
||||||
|
setupAuditLogs();
|
||||||
|
|
||||||
|
WebHdfsFileSystem webfs = WebHdfsTestUtil.getWebHdfsFileSystemAs(userGroupInfo, conf);
|
||||||
|
FileStatus st = webfs.getFileStatus(file);
|
||||||
|
|
||||||
|
verifyAuditLogs(true);
|
||||||
|
assertTrue("failed to stat file", st != null && st.isFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** test that access via Hftp puts proper entry in audit log */
|
||||||
|
@Test
|
||||||
|
public void testAuditHftp() throws Exception {
|
||||||
|
final Path file = new Path(fnames[0]);
|
||||||
|
|
||||||
|
final String hftpUri =
|
||||||
|
"hftp://" + conf.get(DFSConfigKeys.DFS_NAMENODE_HTTP_ADDRESS_KEY);
|
||||||
|
|
||||||
|
HftpFileSystem hftpFs = null;
|
||||||
|
|
||||||
|
setupAuditLogs();
|
||||||
|
try {
|
||||||
|
hftpFs = (HftpFileSystem) new Path(hftpUri).getFileSystem(conf);
|
||||||
|
InputStream istream = hftpFs.open(file);
|
||||||
|
int val = istream.read();
|
||||||
|
istream.close();
|
||||||
|
|
||||||
|
verifyAuditLogs(true);
|
||||||
|
} finally {
|
||||||
|
if (hftpFs != null) hftpFs.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** test that denied access via webhdfs puts proper entry in audit log */
|
||||||
|
@Test
|
||||||
|
public void testAuditWebHdfsDenied() throws Exception {
|
||||||
|
final Path file = new Path(fnames[0]);
|
||||||
|
|
||||||
|
fs.setPermission(file, new FsPermission((short)0600));
|
||||||
|
fs.setOwner(file, "root", null);
|
||||||
|
|
||||||
|
setupAuditLogs();
|
||||||
|
try {
|
||||||
|
WebHdfsFileSystem webfs = WebHdfsTestUtil.getWebHdfsFileSystemAs(userGroupInfo, conf);
|
||||||
|
InputStream istream = webfs.open(file);
|
||||||
|
int val = istream.read();
|
||||||
|
fail("open+read must not succeed, got " + val);
|
||||||
|
} catch(AccessControlException E) {
|
||||||
|
System.out.println("got access denied, as expected.");
|
||||||
|
}
|
||||||
|
verifyAuditLogsRepeat(false, 2);
|
||||||
|
}
|
||||||
|
|
||||||
/** Sets up log4j logger for auditlogs */
|
/** Sets up log4j logger for auditlogs */
|
||||||
private void setupAuditLogs() throws IOException {
|
private void setupAuditLogs() throws IOException {
|
||||||
File file = new File(auditLogFile);
|
File file = new File(auditLogFile);
|
||||||
@ -148,19 +244,34 @@ private void setupAuditLogs() throws IOException {
|
|||||||
logger.addAppender(appender);
|
logger.addAppender(appender);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure audit log has only one entry
|
||||||
private void verifyAuditLogs(boolean expectSuccess) throws IOException {
|
private void verifyAuditLogs(boolean expectSuccess) throws IOException {
|
||||||
|
verifyAuditLogsRepeat(expectSuccess, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure audit log has exactly N entries
|
||||||
|
private void verifyAuditLogsRepeat(boolean expectSuccess, int ndupe)
|
||||||
|
throws IOException {
|
||||||
// Turn off the logs
|
// Turn off the logs
|
||||||
Logger logger = ((Log4JLogger) FSNamesystem.auditLog).getLogger();
|
Logger logger = ((Log4JLogger) FSNamesystem.auditLog).getLogger();
|
||||||
logger.setLevel(Level.OFF);
|
logger.setLevel(Level.OFF);
|
||||||
|
|
||||||
// Ensure audit log has only one entry
|
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(auditLogFile));
|
BufferedReader reader = new BufferedReader(new FileReader(auditLogFile));
|
||||||
String line = reader.readLine();
|
String line = null;
|
||||||
assertNotNull(line);
|
boolean ret = true;
|
||||||
assertTrue("Expected audit event not found in audit log",
|
|
||||||
auditPattern.matcher(line).matches());
|
try {
|
||||||
assertTrue("Expected success=" + expectSuccess,
|
for (int i = 0; i < ndupe; i++) {
|
||||||
successPattern.matcher(line).matches() == expectSuccess);
|
line = reader.readLine();
|
||||||
assertNull("Unexpected event in audit log", reader.readLine());
|
assertNotNull(line);
|
||||||
|
assertTrue("Expected audit event not found in audit log",
|
||||||
|
auditPattern.matcher(line).matches());
|
||||||
|
ret &= successPattern.matcher(line).matches();
|
||||||
|
}
|
||||||
|
assertNull("Unexpected event in audit log", reader.readLine());
|
||||||
|
assertTrue("Expected success=" + expectSuccess, ret == expectSuccess);
|
||||||
|
} finally {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,12 @@ public class TestFsck {
|
|||||||
"ip=/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\s" +
|
"ip=/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\s" +
|
||||||
"cmd=fsck\\ssrc=\\/\\sdst=null\\s" +
|
"cmd=fsck\\ssrc=\\/\\sdst=null\\s" +
|
||||||
"perm=null");
|
"perm=null");
|
||||||
|
static final Pattern getfileinfoPattern = Pattern.compile(
|
||||||
|
"allowed=.*?\\s" +
|
||||||
|
"ugi=.*?\\s" +
|
||||||
|
"ip=/\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\s" +
|
||||||
|
"cmd=getfileinfo\\ssrc=\\/\\sdst=null\\s" +
|
||||||
|
"perm=null");
|
||||||
|
|
||||||
static final Pattern numCorruptBlocksPattern = Pattern.compile(
|
static final Pattern numCorruptBlocksPattern = Pattern.compile(
|
||||||
".*Corrupt blocks:\t\t([0123456789]*).*");
|
".*Corrupt blocks:\t\t([0123456789]*).*");
|
||||||
@ -180,10 +186,14 @@ private void verifyAuditLogs() throws IOException {
|
|||||||
Logger logger = ((Log4JLogger) FSNamesystem.auditLog).getLogger();
|
Logger logger = ((Log4JLogger) FSNamesystem.auditLog).getLogger();
|
||||||
logger.setLevel(Level.OFF);
|
logger.setLevel(Level.OFF);
|
||||||
|
|
||||||
// Ensure audit log has only one for FSCK
|
// Audit log should contain one getfileinfo and one fsck
|
||||||
BufferedReader reader = new BufferedReader(new FileReader(auditLogFile));
|
BufferedReader reader = new BufferedReader(new FileReader(auditLogFile));
|
||||||
String line = reader.readLine();
|
String line = reader.readLine();
|
||||||
assertNotNull(line);
|
assertNotNull(line);
|
||||||
|
assertTrue("Expected getfileinfo event not found in audit log",
|
||||||
|
getfileinfoPattern.matcher(line).matches());
|
||||||
|
line = reader.readLine();
|
||||||
|
assertNotNull(line);
|
||||||
assertTrue("Expected fsck event not found in audit log",
|
assertTrue("Expected fsck event not found in audit log",
|
||||||
fsckPattern.matcher(line).matches());
|
fsckPattern.matcher(line).matches());
|
||||||
assertNull("Unexpected event in audit log", reader.readLine());
|
assertNull("Unexpected event in audit log", reader.readLine());
|
||||||
|
@ -89,7 +89,6 @@ public void testDataLocality() throws Exception {
|
|||||||
//set client address to a particular datanode
|
//set client address to a particular datanode
|
||||||
final DataNode dn = cluster.getDataNodes().get(i);
|
final DataNode dn = cluster.getDataNodes().get(i);
|
||||||
final String ipAddr = dm.getDatanode(dn.getDatanodeId()).getIpAddr();
|
final String ipAddr = dm.getDatanode(dn.getDatanodeId()).getIpAddr();
|
||||||
NamenodeWebHdfsMethods.setRemoteAddress(ipAddr);
|
|
||||||
|
|
||||||
//The chosen datanode must be the same as the client address
|
//The chosen datanode must be the same as the client address
|
||||||
final DatanodeInfo chosen = NamenodeWebHdfsMethods.chooseDatanode(
|
final DatanodeInfo chosen = NamenodeWebHdfsMethods.chooseDatanode(
|
||||||
|
Loading…
Reference in New Issue
Block a user