diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/LogAggregationFileController.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/LogAggregationFileController.java index fe652881af0..551570ad757 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/LogAggregationFileController.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/LogAggregationFileController.java @@ -50,9 +50,9 @@ import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.NodeId; import org.apache.hadoop.yarn.conf.YarnConfiguration; -import org.apache.hadoop.yarn.exceptions.YarnException; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.logaggregation.LogAggregationUtils; +import org.apache.hadoop.yarn.server.security.ApplicationACLsManager; import org.apache.hadoop.yarn.webapp.View.ViewContext; import org.apache.hadoop.yarn.webapp.view.HtmlBlock.Block; import org.slf4j.Logger; @@ -246,6 +246,33 @@ public abstract String getApplicationOwner(Path aggregatedLogPath, public abstract Map getApplicationAcls( Path aggregatedLogPath, ApplicationId appId) throws IOException; + /** + * Validate application acls against expected ACL. + * + * @param conf Configuration + * @param appId the ApplicationId + * @param appOwner App Owner + * @param appAcls Application ACLs + * @param ugi UGI + * @return true if ACL checks pass + */ + + protected boolean checkAcls(Configuration conf, String appOwner, + UserGroupInformation ugi, ApplicationId appId, + Map appAcls, + ApplicationAccessType expectedAccessType) { + + ApplicationACLsManager aclsManager = new ApplicationACLsManager( + conf); + aclsManager.addApplication(appId, appAcls); + + if (ugi != null && !aclsManager.checkAccess(ugi, + expectedAccessType, appOwner, appId)) { + return false; + } + return true; + } + /** * Verify and create the remote log directory. */ diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/ifile/LogAggregationIndexedFileController.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/ifile/LogAggregationIndexedFileController.java index 78b0c134976..fa3d3da4f9c 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/ifile/LogAggregationIndexedFileController.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/ifile/LogAggregationIndexedFileController.java @@ -520,8 +520,8 @@ public boolean readAggregatedLogs(ContainerLogsRequest logRequest, } IndexedLogsMeta indexedLogsMeta = null; try { - indexedLogsMeta = loadIndexedLogsMeta(thisNodeFile.getPath(), - endIndex, appId); + indexedLogsMeta = loadIndexedLogsMeta(thisNodeFile.getPath(), endIndex, + appId); } catch (Exception ex) { // DO NOTHING LOG.warn("Can not load log meta from the log file:" @@ -531,6 +531,18 @@ public boolean readAggregatedLogs(ContainerLogsRequest logRequest, if (indexedLogsMeta == null) { continue; } + + //ACLs check + final Map acls = indexedLogsMeta.getAcls(); + String appOwner = indexedLogsMeta.getUser(); + UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); + if (!checkAcls(conf, appOwner, ugi, appId, acls, + ApplicationAccessType.VIEW_APP)) { + LOG.error("User [" + ugi.getShortUserName() + + "] is not authorized to view the logs for " + nodeName); + continue; + } + String compressAlgo = indexedLogsMeta.getCompressName(); List candidates = new ArrayList<>(); for (IndexedPerAggregationLogMeta logMeta diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/tfile/LogAggregationTFileController.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/tfile/LogAggregationTFileController.java index b3103d29add..0a012920127 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/tfile/LogAggregationTFileController.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/logaggregation/filecontroller/tfile/LogAggregationTFileController.java @@ -39,6 +39,7 @@ import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.RemoteIterator; import org.apache.hadoop.hdfs.protocol.DSQuotaExceededException; +import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.yarn.api.records.ApplicationAccessType; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.conf.YarnConfiguration; @@ -55,6 +56,7 @@ import org.apache.hadoop.yarn.logaggregation.ContainerLogsRequest; import org.apache.hadoop.yarn.logaggregation.LogAggregationUtils; import org.apache.hadoop.yarn.logaggregation.LogToolUtils; +import org.apache.hadoop.yarn.server.security.ApplicationACLsManager; import org.apache.hadoop.yarn.util.Times; import org.apache.hadoop.yarn.webapp.View.ViewContext; import org.apache.hadoop.yarn.webapp.view.HtmlBlock.Block; @@ -190,6 +192,7 @@ public boolean readAggregatedLogs(ContainerLogsRequest logRequest, nodeFiles = HarFs.get(p.toUri(), conf).listStatusIterator(p); continue; } + if ((nodeId == null || nodeName.contains(LogAggregationUtils .getNodeString(nodeId))) && !nodeName.endsWith( LogAggregationUtils.TMP_FILE_SUFFIX)) { @@ -197,6 +200,20 @@ public boolean readAggregatedLogs(ContainerLogsRequest logRequest, try { reader = new AggregatedLogFormat.LogReader(conf, thisNodeFile.getPath()); + + UserGroupInformation ugi = UserGroupInformation.getCurrentUser(); + + try { + if (!checkAcls(conf, reader.getApplicationOwner(), ugi, appId, + reader.getApplicationAcls(), ApplicationAccessType.VIEW_APP)) { + LOG.error("User [" + ugi.getShortUserName() + + "] is not authorized to view the logs for " + nodeName); + continue; + } + } catch (IOException e) { + LOG.error("Error getting logs for " + thisNodeFile.getPath(), e); + } + DataInputStream valueStream; LogKey key = new LogKey(); valueStream = reader.next(key); @@ -213,10 +230,10 @@ public boolean readAggregatedLogs(ContainerLogsRequest logRequest, String fileType = valueStream.readUTF(); String fileLengthStr = valueStream.readUTF(); long fileLength = Long.parseLong(fileLengthStr); - if (logTypes == null || logTypes.isEmpty() || - logTypes.contains(fileType)) { - LogToolUtils.outputContainerLog(key.toString(), - nodeName, fileType, fileLength, size, + if (logTypes == null || logTypes.isEmpty() || logTypes + .contains(fileType)) { + LogToolUtils.outputContainerLog(key.toString(), nodeName, + fileType, fileLength, size, Times.format(thisNodeFile.getModificationTime()), valueStream, os, buf, ContainerLogAggregationType.AGGREGATED); @@ -224,7 +241,7 @@ public boolean readAggregatedLogs(ContainerLogsRequest logRequest, Charset.forName("UTF-8")); os.write(b, 0, b.length); findLogs = true; - } else { + } else{ long totalSkipped = 0; long currSkipped = 0; while (currSkipped != -1 && totalSkipped < fileLength) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/AdminACLsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/AdminACLsManager.java index a386123e6a2..91e4f3f362a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/AdminACLsManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/AdminACLsManager.java @@ -68,7 +68,6 @@ public AdminACLsManager(Configuration conf) { YarnConfiguration.DEFAULT_YARN_ADMIN_ACL)); try { owner = UserGroupInformation.getCurrentUser(); - adminAcl.addUser(owner.getShortUserName()); } catch (IOException e){ LOG.warn("Could not add current user to admin:" + e); throw new YarnRuntimeException(e); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/security/ApplicationACLsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/security/ApplicationACLsManager.java index 97b41633872..fc0b82e93fe 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/security/ApplicationACLsManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/server/security/ApplicationACLsManager.java @@ -27,7 +27,6 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.security.AccessControlException; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authorize.AccessControlList; import org.apache.hadoop.yarn.api.records.ApplicationId;