From ed4ae0e3ea7ef5646e8ecc30143929e21b8aaab4 Mon Sep 17 00:00:00 2001 From: Suma Shivaprasad <sumasai.shivaprasad@gmail.com> Date: Mon, 12 Dec 2016 15:25:31 -0800 Subject: [PATCH] ATLAS-1364 HiveHook : Fix Auth issue with doAs (sumasai) --- addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java | 52 +++++++++++++++++++++++++++++++++++++++------------- notification/src/main/java/org/apache/atlas/hook/AtlasHook.java | 9 ++++++++- release-log.txt | 1 + 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java b/addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java index 91b97f1..cf8851c 100755 --- a/addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java +++ b/addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java @@ -36,9 +36,6 @@ import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.TableType; import org.apache.hadoop.hive.metastore.api.Database; import org.apache.hadoop.hive.metastore.api.FieldSchema; -import org.apache.hadoop.hive.ql.QueryPlan; -import org.apache.hadoop.hive.ql.exec.ExplainTask; -import org.apache.hadoop.hive.ql.exec.Task; import org.apache.hadoop.hive.ql.hooks.*; import org.apache.hadoop.hive.ql.hooks.Entity; import org.apache.hadoop.hive.ql.hooks.Entity.Type; @@ -50,6 +47,7 @@ import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.metadata.Partition; import org.apache.hadoop.hive.ql.metadata.Table; import org.apache.hadoop.hive.ql.plan.HiveOperation; +import org.apache.hadoop.hive.shims.Utils; import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.ShutdownHookManager; import org.json.JSONObject; @@ -59,6 +57,7 @@ import org.slf4j.LoggerFactory; import java.net.MalformedURLException; import java.net.URI; +import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; @@ -73,6 +72,7 @@ import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; +import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; @@ -170,14 +170,14 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext { public void run(final HookContext hookContext) throws Exception { // clone to avoid concurrent access try { - final HiveConf conf = new HiveConf(hookContext.getConf()); - final HiveEventContext event = new HiveEventContext(); event.setInputs(hookContext.getInputs()); event.setOutputs(hookContext.getOutputs()); event.setHookType(hookContext.getHookType()); - event.setUgi(hookContext.getUgi()); - event.setUser(getUser(hookContext.getUserName())); + + final UserGroupInformation ugi = hookContext.getUgi() == null ? Utils.getUGI() : hookContext.getUgi(); + event.setUgi(ugi); + event.setUser(getUser(hookContext.getUserName(), hookContext.getUgi())); event.setOperation(OPERATION_MAP.get(hookContext.getOperationName())); event.setQueryId(hookContext.getQueryPlan().getQueryId()); event.setQueryStr(hookContext.getQueryPlan().getQueryStr()); @@ -186,13 +186,31 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext { event.setLineageInfo(hookContext.getLinfo()); if (executor == null) { - fireAndForget(event); + collect(event); + notifyAsPrivilegedAction(event); } else { executor.submit(new Runnable() { @Override public void run() { try { - fireAndForget(event); + ugi.doAs(new PrivilegedExceptionAction<Object>() { + @Override + public Object run() throws Exception { + collect(event); + return event; + } + }); + + //Notify as 'hive' service user in Kerberos mode else will default to the current user - doAs mode + UserGroupInformation realUser = ugi.getRealUser(); + if (realUser != null) { + LOG.info("Sending notification for event {} as service user {} ", event.getOperation(), realUser.getShortUserName()); + realUser.doAs(notifyAsPrivilegedAction(event)); + } else { + //Unsecure or without doAs + LOG.info("Sending notification for event {} as current user {} ", event.getOperation(), ugi.getShortUserName()); + ugi.doAs(notifyAsPrivilegedAction(event)); + } } catch (Throwable e) { LOG.error("Atlas hook failed due to error ", e); } @@ -204,11 +222,21 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext { } } - private void fireAndForget(HiveEventContext event) throws Exception { + PrivilegedExceptionAction<Object> notifyAsPrivilegedAction(final HiveEventContext event) { + return new PrivilegedExceptionAction<Object>() { + @Override + public Object run() throws Exception { + notifyEntities(event.getMessages()); + return event; + } + }; + } + + private void collect(HiveEventContext event) throws Exception { assert event.getHookType() == HookContext.HookType.POST_EXEC_HOOK : "Non-POST_EXEC_HOOK not supported!"; - LOG.info("Entered Atlas hook for hook type {} operation {}", event.getHookType(), event.getOperation()); + LOG.info("Entered Atlas hook for hook type {}, operation {} , user {} as {}", event.getHookType(), event.getOperation(), event.getUgi().getRealUser(), event.getUgi().getShortUserName()); HiveMetaStoreBridge dgiBridge = new HiveMetaStoreBridge(atlasProperties, hiveConf); @@ -280,8 +308,6 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext { default: } - - notifyEntities(event.getMessages()); } private void deleteTable(HiveMetaStoreBridge dgiBridge, HiveEventContext event) { diff --git a/notification/src/main/java/org/apache/atlas/hook/AtlasHook.java b/notification/src/main/java/org/apache/atlas/hook/AtlasHook.java index 04ee9c0..5bdd5d3 100644 --- a/notification/src/main/java/org/apache/atlas/hook/AtlasHook.java +++ b/notification/src/main/java/org/apache/atlas/hook/AtlasHook.java @@ -189,18 +189,25 @@ public abstract class AtlasHook { public static String getUser(String userName, UserGroupInformation ugi) { if (StringUtils.isNotEmpty(userName)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Returning userName {} " + userName); + } return userName; } if (ugi != null && StringUtils.isNotEmpty(ugi.getShortUserName())) { + if (LOG.isDebugEnabled()) { + LOG.debug("Returning ugi.getShortUserName {} " + userName); + } return ugi.getShortUserName(); } try { return UserGroupInformation.getCurrentUser().getShortUserName(); } catch (IOException e) { - LOG.warn("Failed for UserGroupInformation.getCurrentUser()"); + LOG.warn("Failed for UserGroupInformation.getCurrentUser() ", e); return System.getProperty("user.name"); } } + } diff --git a/release-log.txt b/release-log.txt index 270ffeb..b8786ad 100644 --- a/release-log.txt +++ b/release-log.txt @@ -9,6 +9,7 @@ ATLAS-1060 Add composite indexes for exact match performance improvements for al ATLAS-1127 Modify creation and modification timestamps to Date instead of Long(sumasai) ALL CHANGES: +ATLAS-1364 HiveHook : Fix Auth issue with doAs (sumasai) ATLAS-1340 Credential Provider utility does not work with fully qualified local/HDFS jceks path (vrathor via svimal2106) ATLAS-1363 Upgrade front end maven plugin to 1.0 (sumasai) ATLAS-1358 NPE Fix for search filter changes & callAPI related fixes (apoorvnaik via sumasai) -- libgit2 0.27.1