You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by me...@apache.org on 2019/05/20 13:27:11 UTC

[ranger] branch master updated: RANGER-2395 : Add Presto plugin, This implements a plugin for Presto, a distributed SQL engine.

This is an automated email from the ASF dual-hosted git repository.

mehul pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 43757e7  RANGER-2395 : Add Presto plugin, This implements a plugin for Presto, a distributed SQL engine.
43757e7 is described below

commit 43757e798751ffab99dbe15ab3f9ae0773ae69f7
Author: Bolke de Bruin <bo...@xs4all.nl>
AuthorDate: Mon May 6 20:00:53 2019 +0200

    RANGER-2395 : Add Presto plugin, This implements a plugin for Presto, a distributed SQL engine.
    
    Signed-off-by: Mehul Parikh <me...@apache.org>
---
 agents-common/scripts/enable-agent.sh              |  31 ++
 .../plugin/store/EmbeddedServiceDefsUtil.java      |   8 +-
 .../service-defs/ranger-servicedef-presto.json     | 197 ++++++++
 .../conf/ranger-policymgr-ssl-changes.cfg          |  21 +
 plugin-presto/conf/ranger-policymgr-ssl.xml        |  49 ++
 plugin-presto/conf/ranger-presto-audit-changes.cfg |  58 +++
 plugin-presto/conf/ranger-presto-audit.xml         | 271 ++++++++++
 .../conf/ranger-presto-security-changes.cfg        |  28 ++
 plugin-presto/conf/ranger-presto-security.xml      |  74 +++
 plugin-presto/pom.xml                              |  56 +++
 plugin-presto/scripts/install.properties           | 140 ++++++
 .../authorizer/RangerSystemAccessControl.java      | 459 +++++++++++++++++
 .../services/presto/RangerServicePresto.java       |  86 ++++
 .../services/presto/client/PrestoClient.java       | 556 +++++++++++++++++++++
 .../presto/client/PrestoConnectionManager.java     |  93 ++++
 .../presto/client/PrestoResourceManager.java       | 178 +++++++
 pom.xml                                            |  40 ++
 ranger-presto-plugin-shim/pom.xml                  | 105 ++++
 .../presto/authorizer/PrestoRangerPlugin.java      |  32 ++
 .../presto/authorizer/RangerConfig.java            |  47 ++
 .../authorizer/RangerSystemAccessControl.java      | 382 ++++++++++++++
 .../RangerSystemAccessControlFactory.java          |  61 +++
 .../META-INF/services/io.prestosql.spi.Plugin      |  15 +
 src/main/assembly/admin-web.xml                    |  21 +
 src/main/assembly/plugin-presto.xml                | 202 ++++++++
 25 files changed, 3209 insertions(+), 1 deletion(-)

diff --git a/agents-common/scripts/enable-agent.sh b/agents-common/scripts/enable-agent.sh
index b4194a7..7dec0b1 100755
--- a/agents-common/scripts/enable-agent.sh
+++ b/agents-common/scripts/enable-agent.sh
@@ -212,6 +212,12 @@ elif [ "${HCOMPONENT_NAME}" = "kylin" ]; then
     HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/tomcat/webapps/kylin/WEB-INF/lib
 elif [ "${HCOMPONENT_NAME}" = "elasticsearch" ]; then
     HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/plugins
+elif [ "${HCOMPONENT_NAME}" = "presto" ]; then
+    HCOMPONENT_LIB_DIR=${HCOMPONENT_INSTALL_DIR}/plugins/ranger
+    if [ ! -d "${HCOMPONENT_LIB_DIR}" ]; then
+        echo "INFO: Creating ${HCOMPONENT_LIB_DIR}"
+        mkdir -p ${HCOMPONENT_LIB_DIR}
+    fi
 fi
 
 HCOMPONENT_CONF_DIR=${HCOMPONENT_INSTALL_DIR}/conf
@@ -240,6 +246,8 @@ elif [ "${HCOMPONENT_NAME}" = "elasticsearch" ]; then
 	echo "INFO: Changing ownership of $HCOMPONENT_CONF_DIR to $CFG_OWNER_INF"
 	chown $CFG_OWNER_INF $HCOMPONENT_CONF_DIR
     fi
+elif [ "${HCOMPONENT_NAME}" = "presto" ]; then
+    HCOMPONENT_CONF_DIR=${HCOMPONENT_INSTALL_DIR}/etc
 fi
 
 HCOMPONENT_ARCHIVE_CONF_DIR=${HCOMPONENT_CONF_DIR}/.archive
@@ -773,6 +781,29 @@ then
 	fi
 fi
 
+if [ "${HCOMPONENT_NAME}" = "presto" ]
+then
+	if [ "${action}" = "enable" ]
+	then
+		controlName="ranger"
+	else
+		controlName=""
+	fi
+	dt=`date '+%Y%m%d%H%M%S'`
+	fn=`ls ${HCOMPONENT_CONF_DIR}/access-control.properties 2> /dev/null`
+	if [ -f "${fn}" ]
+	then
+		dn=`dirname ${fn}`
+		bn=`basename ${fn}`
+		bf=${dn}/.${bn}.${dt}
+		echo "backup of ${fn} to ${bf} ..."
+		cp ${fn} ${bf}
+		echo "Add or Update properties file: [${fn}] ... "
+		addOrUpdatePropertyToFile access-control.name $controlName ${fn}
+	fi
+fi
+
+
 #
 # Set notice to restart the ${HCOMPONENT_NAME}
 #
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
index cbfd649..d82fd70 100755
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
@@ -48,7 +48,7 @@ public class EmbeddedServiceDefsUtil {
 
 
 	// following servicedef list should be reviewed/updated whenever a new embedded service-def is added
-	public static final String DEFAULT_BOOTSTRAP_SERVICEDEF_LIST = "tag,hdfs,hbase,hive,kms,knox,storm,yarn,kafka,solr,atlas,nifi,nifi-registry,sqoop,kylin,elasticsearch";
+	public static final String DEFAULT_BOOTSTRAP_SERVICEDEF_LIST = "tag,hdfs,hbase,hive,kms,knox,storm,yarn,kafka,solr,atlas,nifi,nifi-registry,sqoop,kylin,elasticsearch,presto";
 	private static final String PROPERTY_SUPPORTED_SERVICE_DEFS = "ranger.supportedcomponents";
 	private Set<String> supportedServiceDefs;
 	public static final String EMBEDDED_SERVICEDEF_TAG_NAME  = "tag";
@@ -69,6 +69,7 @@ public class EmbeddedServiceDefsUtil {
 	public static final String EMBEDDED_SERVICEDEF_KYLIN_NAME  = "kylin";
 	public static final String EMBEDDED_SERVICEDEF_ABFS_NAME  = "abfs";
 	public static final String EMBEDDED_SERVICEDEF_ELASTICSEARCH_NAME = "elasticsearch";
+	public static final String EMBEDDED_SERVICEDEF_PRESTO_NAME  = "presto";
 
 	public static final String PROPERTY_CREATE_EMBEDDED_SERVICE_DEFS = "ranger.service.store.create.embedded.service-defs";
 
@@ -83,6 +84,7 @@ public class EmbeddedServiceDefsUtil {
 	public static final String SOLR_IMPL_CLASS_NAME  = "org.apache.ranger.services.solr.RangerServiceSolr";
 	public static final String NIFI_IMPL_CLASS_NAME  = "org.apache.ranger.services.nifi.RangerServiceNiFi";
 	public static final String ATLAS_IMPL_CLASS_NAME  = "org.apache.ranger.services.atlas.RangerServiceAtlas";
+	public static final String PRESTO_IMPL_CLASS_NAME  = "org.apache.ranger.services.presto.RangerServicePresto";
 
 	private static EmbeddedServiceDefsUtil instance = new EmbeddedServiceDefsUtil();
 
@@ -104,6 +106,7 @@ public class EmbeddedServiceDefsUtil {
 	private RangerServiceDef kylinServiceDef;
 	private RangerServiceDef abfsServiceDef;
 	private RangerServiceDef elasticsearchServiceDef;
+	private RangerServiceDef prestoServiceDef;
 
 	private RangerServiceDef tagServiceDef;
 
@@ -148,6 +151,7 @@ public class EmbeddedServiceDefsUtil {
 			kylinServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_KYLIN_NAME);
 			abfsServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_ABFS_NAME);
 			elasticsearchServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_ELASTICSEARCH_NAME);
+			prestoServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_PRESTO_NAME);
 
 			// Ensure that tag service def is updated with access types of all service defs
 			store.updateTagServiceDefForAccessTypes();
@@ -223,6 +227,8 @@ public class EmbeddedServiceDefsUtil {
 
 	public long getAbfsServiceDefId() { return getId(abfsServiceDef); }
 
+	public long getPrestoServiceDefId() { return getId(prestoServiceDef); }
+
 	public RangerServiceDef getEmbeddedServiceDef(String defType) throws Exception {
 		RangerServiceDef serviceDef=null;
 		if(StringUtils.isNotEmpty(defType)){
diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-presto.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-presto.json
new file mode 100644
index 0000000..f0ecf6b
--- /dev/null
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-presto.json
@@ -0,0 +1,197 @@
+{
+  "id": 17,
+  "name": "presto",
+  "implClass": "org.apache.ranger.services.presto.RangerServicePresto",
+  "label": "Presto",
+  "description": "Presto",
+  "guid": "379a9fe5-1b6e-4091-a584-4890e245e6c1",
+  "resources": [
+    {
+      "itemId": 1,
+      "name": "catalog",
+      "type": "string",
+      "level": 10,
+      "parent": "",
+      "mandatory": true,
+      "isValidLeaf": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard": true,
+        "ignoreCase": true
+      },
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Presto Catalog",
+      "description": "Presto Catalog"
+    },
+    {
+      "itemId": 2,
+      "name": "schema",
+      "type": "string",
+      "level": 20,
+      "parent": "catalog",
+      "mandatory": true,
+      "isValidLeaf": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard": true,
+        "ignoreCase": true
+      },
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Presto Schema",
+      "description": "Presto Schema"
+    },
+    {
+      "itemId": 3,
+      "name": "table",
+      "type": "string",
+      "level": 30,
+      "parent": "schema",
+      "mandatory": true,
+      "isValidLeaf": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard": true,
+        "ignoreCase": true
+      },
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Presto Table",
+      "description": "Presto Table"
+    },
+    {
+      "itemId": 4,
+      "name": "column",
+      "type": "string",
+      "level": 40,
+      "parent": "table",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard": true,
+        "ignoreCase": true
+      },
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Presto Column",
+      "description": "Presto Column"
+    }
+  ],
+  "accessTypes": [
+    {
+      "itemId": 1,
+      "name": "select",
+      "label": "Select"
+    },
+    {
+      "itemId": 2,
+      "name": "update",
+      "label": "Update"
+    },
+    {
+      "itemId": 3,
+      "name": "create",
+      "label": "Create"
+    },
+    {
+      "itemId": 4,
+      "name": "drop",
+      "label": "Drop"
+    },
+    {
+      "itemId": 5,
+      "name": "use",
+      "label": "Use"
+    },
+    {
+      "itemId": 6,
+      "name": "alter",
+      "label": "Alter"
+    },
+    {
+      "itemId": 7,
+      "name": "admin",
+      "label": "Admin"
+    },
+    {
+      "itemId": 8,
+      "name": "all",
+      "label": "All",
+      "impliedGrants": [
+        "select",
+        "update",
+        "create",
+        "drop",
+        "use",
+        "alter",
+        "admin"
+      ]
+    }
+  ],
+  "configs": [
+    {
+      "itemId": 1,
+      "name": "username",
+      "type": "string",
+      "mandatory": true,
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Username"
+    },
+    {
+      "itemId": 2,
+      "name": "password",
+      "type": "password",
+      "mandatory": false,
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "label": "Password"
+    },
+    {
+      "itemId": 3,
+      "name": "jdbc.driverClassName",
+      "type": "string",
+      "mandatory": true,
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": "",
+      "defaultValue": "io.prestosql.jdbc.PrestoDriver"
+    },
+    {
+      "itemId": 4,
+      "name": "jdbc.url",
+      "type": "string",
+      "mandatory": true,
+      "defaultValue": "",
+      "validationRegEx": "",
+      "validationMessage": "",
+      "uiHint": ""
+    }
+  ],
+  "enums": [
+  ],
+  "contextEnrichers": [
+  ],
+  "policyConditions":
+  [
+  ]
+}
\ No newline at end of file
diff --git a/plugin-presto/conf/ranger-policymgr-ssl-changes.cfg b/plugin-presto/conf/ranger-policymgr-ssl-changes.cfg
new file mode 100644
index 0000000..ae347e8
--- /dev/null
+++ b/plugin-presto/conf/ranger-policymgr-ssl-changes.cfg
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SSL Params
+#
+xasecure.policymgr.clientssl.keystore					 %SSL_KEYSTORE_FILE_PATH%						mod create-if-not-exists
+xasecure.policymgr.clientssl.keystore.credential.file	 jceks://file%CREDENTIAL_PROVIDER_FILE%			mod create-if-not-exists
+xasecure.policymgr.clientssl.truststore				     %SSL_TRUSTSTORE_FILE_PATH%						mod create-if-not-exists
+xasecure.policymgr.clientssl.truststore.credential.file  jceks://file%CREDENTIAL_PROVIDER_FILE%         mod create-if-not-exists
diff --git a/plugin-presto/conf/ranger-policymgr-ssl.xml b/plugin-presto/conf/ranger-policymgr-ssl.xml
new file mode 100644
index 0000000..5ac7cf1
--- /dev/null
+++ b/plugin-presto/conf/ranger-policymgr-ssl.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
+    <!--  The following properties are used for 2-way SSL client server validation -->
+    <property>
+        <name>xasecure.policymgr.clientssl.keystore</name>
+        <value>prestoservice-clientcert.jks</value>
+        <description>
+            Java Keystore files
+        </description>
+    </property>
+    <property>
+        <name>xasecure.policymgr.clientssl.truststore</name>
+        <value>cacerts-xasecure.jks</value>
+        <description>
+            java truststore file
+        </description>
+    </property>
+    <property>
+        <name>xasecure.policymgr.clientssl.keystore.credential.file</name>
+        <value>jceks://file/tmp/keystore-prestoservice-ssl.jceks</value>
+        <description>
+            java  keystore credential file
+        </description>
+    </property>
+    <property>
+        <name>xasecure.policymgr.clientssl.truststore.credential.file</name>
+        <value>jceks://file/tmp/truststore-prestoservice-ssl.jceks</value>
+        <description>
+            java  truststore credential file
+        </description>
+    </property>
+</configuration>
diff --git a/plugin-presto/conf/ranger-presto-audit-changes.cfg b/plugin-presto/conf/ranger-presto-audit-changes.cfg
new file mode 100644
index 0000000..661b498
--- /dev/null
+++ b/plugin-presto/conf/ranger-presto-audit-changes.cfg
@@ -0,0 +1,58 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#xasecure.audit.db.is.enabled                        %XAAUDIT.DB.IS_ENABLED%                                         mod create-if-not-exists
+#xasecure.audit.jpa.javax.persistence.jdbc.url		%XAAUDIT_DB_JDBC_URL%											mod create-if-not-exists
+#xasecure.audit.jpa.javax.persistence.jdbc.user		%XAAUDIT.DB.USER_NAME% 											mod create-if-not-exists
+#xasecure.audit.jpa.javax.persistence.jdbc.password	crypted	 														mod create-if-not-exists
+#xasecure.audit.credential.provider.file     		jceks://file%CREDENTIAL_PROVIDER_FILE% 							mod create-if-not-exists
+#xasecure.audit.jpa.javax.persistence.jdbc.driver	%XAAUDIT_DB_JDBC_DRIVER% 										mod create-if-not-exists
+
+xasecure.audit.hdfs.is.enabled                                     %XAAUDIT.HDFS.IS_ENABLED%                               mod create-if-not-exists
+xasecure.audit.hdfs.config.destination.directory                   %XAAUDIT.HDFS.DESTINATION_DIRECTORY%                    mod create-if-not-exists
+xasecure.audit.hdfs.config.destination.file                        %XAAUDIT.HDFS.DESTINTATION_FILE%                        mod create-if-not-exists
+xasecure.audit.hdfs.config.destination.flush.interval.seconds      %XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS%      mod create-if-not-exists
+xasecure.audit.hdfs.config.destination.rollover.interval.seconds   %XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS%   mod create-if-not-exists
+xasecure.audit.hdfs.config.destination.open.retry.interval.seconds %XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS% mod create-if-not-exists
+xasecure.audit.hdfs.config.local.buffer.directory                  %XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY%                   mod create-if-not-exists
+xasecure.audit.hdfs.config.local.buffer.file                       %XAAUDIT.HDFS.LOCAL_BUFFER_FILE%                        mod create-if-not-exists
+xasecure.audit.hdfs.config.local.buffer.flush.interval.seconds     %XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS%      mod create-if-not-exists
+xasecure.audit.hdfs.config.local.buffer.rollover.interval.seconds  %XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS%   mod create-if-not-exists
+xasecure.audit.hdfs.config.local.archive.directory                 %XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY%                  mod create-if-not-exists
+xasecure.audit.hdfs.config.local.archive.max.file.count            %XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT%             mod create-if-not-exists
+
+xasecure.audit.solr.is.enabled                                    %XAAUDIT.SOLR.IS_ENABLED%                               mod create-if-not-exists
+xasecure.audit.solr.solr_url                                      %XAAUDIT.SOLR.SOLR_URL%                                 mod create-if-not-exists
+
+#V3 configuration
+xasecure.audit.provider.summary.enabled				  %XAAUDIT.SUMMARY.ENABLE%				mod create-if-not-exists
+
+xasecure.audit.destination.solr                                    %XAAUDIT.SOLR.ENABLE%                               mod create-if-not-exists
+xasecure.audit.destination.solr.urls                               %XAAUDIT.SOLR.URL%                                 mod create-if-not-exists
+xasecure.audit.destination.solr.user %XAAUDIT.SOLR.USER% mod create-if-not-exists
+xasecure.audit.destination.solr.password %XAAUDIT.SOLR.PASSWORD% mod create-if-not-exists
+xasecure.audit.destination.solr.zookeepers                         %XAAUDIT.SOLR.ZOOKEEPER%                           mod create-if-not-exists
+xasecure.audit.destination.solr.batch.filespool.dir                %XAAUDIT.SOLR.FILE_SPOOL_DIR%                      mod create-if-not-exists
+
+xasecure.audit.destination.hdfs					   %XAAUDIT.HDFS.ENABLE%                      mod create-if-not-exists
+xasecure.audit.destination.hdfs.batch.filespool.dir                %XAAUDIT.HDFS.FILE_SPOOL_DIR%                      mod create-if-not-exists
+xasecure.audit.destination.hdfs.dir                		   %XAAUDIT.HDFS.HDFS_DIR%                      mod create-if-not-exists
+
+AZURE.ACCOUNTNAME                                                                                                 %XAAUDIT.HDFS.AZURE_ACCOUNTNAME%            var
+xasecure.audit.destination.hdfs.config.fs.azure.shellkeyprovider.script                                           %XAAUDIT.HDFS.AZURE_SHELL_KEY_PROVIDER%     mod         create-if-not-exists
+xasecure.audit.destination.hdfs.config.fs.azure.account.key.%AZURE.ACCOUNTNAME%.blob.core.windows.net             %XAAUDIT.HDFS.AZURE_ACCOUNTKEY%             mod         create-if-not-exists
+xasecure.audit.destination.hdfs.config.fs.azure.account.keyprovider.%AZURE.ACCOUNTNAME%.blob.core.windows.net     %XAAUDIT.HDFS.AZURE_ACCOUNTKEY_PROVIDER%    mod         create-if-not-exists
+
+#xasecure.audit.destination.file					   %XAAUDIT.FILE.ENABLE%                      mod create-if-not-exists
+#xasecure.audit.destination.file.dir                		   %XAAUDIT.FILE.DIR%                      mod create-if-not-exists
diff --git a/plugin-presto/conf/ranger-presto-audit.xml b/plugin-presto/conf/ranger-presto-audit.xml
new file mode 100644
index 0000000..c72771e
--- /dev/null
+++ b/plugin-presto/conf/ranger-presto-audit.xml
@@ -0,0 +1,271 @@
+<?xml version="1.0"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude">
+    <property>
+        <name>xasecure.audit.is.enabled</name>
+        <value>true</value>
+    </property>
+
+
+    <!-- DB audit provider configuration -->
+    <property>
+        <name>xasecure.audit.db.is.enabled</name>
+        <value>false</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.db.is.async</name>
+        <value>true</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.db.async.max.queue.size</name>
+        <value>10240</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.db.async.max.flush.interval.ms</name>
+        <value>30000</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.db.batch.size</name>
+        <value>100</value>
+    </property>
+
+    <!--  Properties whose name begin with "xasecure.audit.jpa." are used to configure JPA -->
+    <property>
+        <name>xasecure.audit.jpa.javax.persistence.jdbc.url</name>
+        <value>jdbc:mysql://localhost:3306/ranger_audit</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.jpa.javax.persistence.jdbc.user</name>
+        <value>rangerlogger</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.jpa.javax.persistence.jdbc.password</name>
+        <value>none</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.jpa.javax.persistence.jdbc.driver</name>
+        <value>com.mysql.jdbc.Driver</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.credential.provider.file</name>
+        <value>jceks://file/etc/ranger/prestodev/auditcred.jceks</value>
+    </property>
+
+
+
+    <!-- HDFS audit provider configuration -->
+    <property>
+        <name>xasecure.audit.hdfs.is.enabled</name>
+        <value>false</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.is.async</name>
+        <value>true</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.async.max.queue.size</name>
+        <value>1048576</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.async.max.flush.interval.ms</name>
+        <value>30000</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.encoding</name>
+        <value></value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.destination.directory</name>
+        <value>hdfs://NAMENODE_HOST:8020/ranger/audit/%app-type%/%time:yyyyMMdd%</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.destination.file</name>
+        <value>%hostname%-audit.log</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.destination.flush.interval.seconds</name>
+        <value>900</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.destination.rollover.interval.seconds</name>
+        <value>86400</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.destination.open.retry.interval.seconds</name>
+        <value>60</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.local.buffer.directory</name>
+        <value>/var/log/presto/audit</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.local.buffer.file</name>
+        <value>%time:yyyyMMdd-HHmm.ss%.log</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.local.buffer.file.buffer.size.bytes</name>
+        <value>8192</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.local.buffer.flush.interval.seconds</name>
+        <value>60</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.local.buffer.rollover.interval.seconds</name>
+        <value>600</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.local.archive.directory</name>
+        <value>/var/log/presto/audit/archive</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.hdfs.config.local.archive.max.file.count</name>
+        <value>10</value>
+    </property>
+
+    <!-- Audit to HDFS on Azure Datastore (WASB) requires v3 style settings.  Comment the above and uncomment only the
+    following to audit to Azure Blob Datastore via hdfs' WASB schema.
+
+    NOTE: If you specify one audit destination in v3 style then other destinations, if any, must also be specified in v3 style
+    ====
+
+    <property>
+        <name>xasecure.audit.destination.hdfs</name>
+        <value>enabled</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.destination.hdfs.dir</name>
+        <value>wasb://ranger-audit1@youraccount.blob.core.windows.net</value>
+    </property>
+
+    the following 3 correspond to the properties with similar name in core-site.xml, i.e.
+    - fs.azure.account.key.youraccount.blob.core.windows.net => xasecure.audit.destination.hdfs.config.fs.azure.account.key.youraccount.blob.core.windows.net and
+    - fs.azure.account.keyprovider.youraccount.blob.core.windows.net => xasecure.audit.destination.hdfs.config.fs.azure.account.keyprovider.youraccount.blob.core.windows.net,
+    - fs.azure.shellkeyprovider.script => xasecure.audit.destination.hdfs.config.fs.azure.shellkeyprovider.script,
+
+    <property>
+        <name>xasecure.audit.destination.hdfs.config.fs.azure.account.key.youraccount.blob.core.windows.net</name>
+        <value>YOUR ENCRYPTED ACCESS KEY</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.destination.hdfs.config.fs.azure.account.keyprovider.youraccount.blob.core.windows.net</name>
+        <value>org.apache.hadoop.fs.azure.ShellDecryptionKeyProvider</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.destination.hdfs.config.fs.azure.shellkeyprovider.script</name>
+        <value>/usr/lib/python2.7/dist-packages/hdinsight_common/decrypt.sh</value>
+    </property>
+    -->
+
+    <!-- Log4j audit provider configuration -->
+    <property>
+        <name>xasecure.audit.log4j.is.enabled</name>
+        <value>false</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.log4j.is.async</name>
+        <value>false</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.log4j.async.max.queue.size</name>
+        <value>10240</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.log4j.async.max.flush.interval.ms</name>
+        <value>30000</value>
+    </property>
+
+
+    <!-- presto audit provider configuration -->
+    <property>
+        <name>xasecure.audit.presto.is.enabled</name>
+        <value>false</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.presto.async.max.queue.size</name>
+        <value>1</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.presto.async.max.flush.interval.ms</name>
+        <value>1000</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.presto.broker_list</name>
+        <value>localhost:9092</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.presto.topic_name</name>
+        <value>ranger_audits</value>
+    </property>
+
+    <!-- Ranger audit provider configuration -->
+    <property>
+        <name>xasecure.audit.solr.is.enabled</name>
+        <value>false</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.solr.async.max.queue.size</name>
+        <value>1</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.solr.async.max.flush.interval.ms</name>
+        <value>1000</value>
+    </property>
+
+    <property>
+        <name>xasecure.audit.solr.solr_url</name>
+        <value>http://localhost:6083/solr/ranger_audits</value>
+    </property>
+</configuration>
diff --git a/plugin-presto/conf/ranger-presto-security-changes.cfg b/plugin-presto/conf/ranger-presto-security-changes.cfg
new file mode 100644
index 0000000..15fc7fd
--- /dev/null
+++ b/plugin-presto/conf/ranger-presto-security-changes.cfg
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Change the original policy parameter to work with policy manager based.
+#
+#
+ranger.plugin.presto.service.name %REPOSITORY_NAME% mod create-if-not-exists
+
+ranger.plugin.presto.policy.source.impl org.apache.ranger.admin.client.RangerAdminRESTClient mod create-if-not-exists
+
+ranger.plugin.presto.policy.rest.url                %POLICY_MGR_URL%                          mod create-if-not-exists
+ranger.plugin.presto.policy.rest.ssl.config.file    /etc/hadoop/conf/ranger-policymgr-ssl.xml mod create-if-not-exists
+ranger.plugin.presto.policy.pollIntervalMs          30000                                     mod create-if-not-exists
+ranger.plugin.presto.policy.cache.dir               %POLICY_CACHE_FILE_PATH%                  mod create-if-not-exists
+ranger.plugin.presto.policy.rest.client.connection.timeoutMs 	  120000					    mod create-if-not-exists
+ranger.plugin.presto.policy.rest.client.read.timeoutMs	   	  30000					        mod create-if-not-exists
\ No newline at end of file
diff --git a/plugin-presto/conf/ranger-presto-security.xml b/plugin-presto/conf/ranger-presto-security.xml
new file mode 100644
index 0000000..9feae81
--- /dev/null
+++ b/plugin-presto/conf/ranger-presto-security.xml
@@ -0,0 +1,74 @@
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<configuration>
+  <property>
+    <name>ranger.plugin.presto.service.name</name>
+    <value>prestoservice</value>
+    <description>
+      Name of the Ranger service containing policies for this Presto instance
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.presto.policy.source.impl</name>
+    <value>org.apache.ranger.admin.client.RangerAdminRESTClient</value>
+    <description>
+      Class to retrieve policies from the source
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.presto.policy.rest.url</name>
+    <value>http://localhost:6080</value>
+    <description>
+      URL to Ranger Admin
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.presto.policy.rest.ssl.config.file</name>
+    <value>/etc/hadoop/conf/ranger-policymgr-ssl.xml</value>
+    <description>
+      Path to the file containing SSL details to contact Ranger Admin
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.presto.policy.pollIntervalMs</name>
+    <value>30000</value>
+    <description>
+      How often to poll for changes in policies?
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.presto.policy.rest.client.connection.timeoutMs</name>
+    <value>30000</value>
+    <description>
+      S3 Plugin RangerRestClient Connection Timeout in Milli Seconds
+    </description>
+  </property>
+
+  <property>
+    <name>ranger.plugin.presto.policy.rest.client.read.timeoutMs</name>
+    <value>30000</value>
+    <description>
+      S3 Plugin RangerRestClient read Timeout in Milli Seconds
+    </description>
+  </property>
+</configuration>
diff --git a/plugin-presto/pom.xml b/plugin-presto/pom.xml
new file mode 100644
index 0000000..f066d31
--- /dev/null
+++ b/plugin-presto/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>ranger-presto-plugin</artifactId>
+    <name>Presto Security Plugin</name>
+    <description>Presto Security Plugin</description>
+    <packaging>jar</packaging>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <parent>
+        <groupId>org.apache.ranger</groupId>
+        <artifactId>ranger</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>io.prestosql</groupId>
+            <artifactId>presto-spi</artifactId>
+            <version>${presto.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.prestosql</groupId>
+            <artifactId>presto-jdbc</artifactId>
+            <version>${presto.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-audit</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/plugin-presto/scripts/install.properties b/plugin-presto/scripts/install.properties
new file mode 100644
index 0000000..3110e2d
--- /dev/null
+++ b/plugin-presto/scripts/install.properties
@@ -0,0 +1,140 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# Location of Policy Manager URL
+#
+# Example:
+# POLICY_MGR_URL=http://policymanager.xasecure.net:6080
+#
+POLICY_MGR_URL=
+
+#
+# This is the repository name created within policy manager
+#
+# Example:
+# REPOSITORY_NAME=prestodev
+#
+REPOSITORY_NAME=
+
+#
+# Name of the directory where the component's lib and conf directory exist.
+# This location should be relative to the parent of the directory containing
+# the plugin installation files.
+#
+COMPONENT_INSTALL_DIR_NAME=../presto
+
+# Enable audit logs to Solr
+#Example
+#XAAUDIT.SOLR.ENABLE=true
+#XAAUDIT.SOLR.URL=http://localhost:6083/solr/ranger_audits
+#XAAUDIT.SOLR.ZOOKEEPER=
+#XAAUDIT.SOLR.FILE_SPOOL_DIR=/var/log/presto/audit/solr/spool
+
+XAAUDIT.SOLR.ENABLE=false
+XAAUDIT.SOLR.URL=NONE
+XAAUDIT.SOLR.USER=NONE
+XAAUDIT.SOLR.PASSWORD=NONE
+XAAUDIT.SOLR.ZOOKEEPER=NONE
+XAAUDIT.SOLR.FILE_SPOOL_DIR=/var/log/presto/audit/solr/spool
+
+# Enable audit logs to HDFS
+#Example
+#XAAUDIT.HDFS.ENABLE=true
+#XAAUDIT.HDFS.HDFS_DIR=hdfs://node-1.example.com:8020/ranger/audit
+#  If using Azure Blob Storage
+#XAAUDIT.HDFS.HDFS_DIR=wasb[s]://<containername>@<accountname>.blob.core.windows.net/<path>
+#XAAUDIT.HDFS.HDFS_DIR=wasb://ranger_audit_container@my-azure-account.blob.core.windows.net/ranger/audit
+#XAAUDIT.HDFS.FILE_SPOOL_DIR=/var/log/presto/audit/hdfs/spool
+
+XAAUDIT.HDFS.ENABLE=false
+XAAUDIT.HDFS.HDFS_DIR=hdfs://__REPLACE__NAME_NODE_HOST:8020/ranger/audit
+XAAUDIT.HDFS.FILE_SPOOL_DIR=/var/log/presto/audit/hdfs/spool
+
+# Following additional propertis are needed When auditing to Azure Blob Storage via HDFS
+# Get these values from your /etc/hadoop/conf/core-site.xml
+#XAAUDIT.HDFS.HDFS_DIR=wasb[s]://<containername>@<accountname>.blob.core.windows.net/<path>
+XAAUDIT.HDFS.AZURE_ACCOUNTNAME=__REPLACE_AZURE_ACCOUNT_NAME
+XAAUDIT.HDFS.AZURE_ACCOUNTKEY=__REPLACE_AZURE_ACCOUNT_KEY
+XAAUDIT.HDFS.AZURE_SHELL_KEY_PROVIDER=__REPLACE_AZURE_SHELL_KEY_PROVIDER
+XAAUDIT.HDFS.AZURE_ACCOUNTKEY_PROVIDER=__REPLACE_AZURE_ACCOUNT_KEY_PROVIDER
+
+# End of V3 properties
+
+
+#
+#  Audit to HDFS Configuration
+#
+# If XAAUDIT.HDFS.IS_ENABLED is set to true, please replace tokens
+# that start with __REPLACE__ with appropriate values
+#  XAAUDIT.HDFS.IS_ENABLED=true
+#  XAAUDIT.HDFS.DESTINATION_DIRECTORY=hdfs://__REPLACE__NAME_NODE_HOST:8020/ranger/audit/%app-type%/%time:yyyyMMdd%
+#  XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY=__REPLACE__LOG_DIR/presto/audit
+#  XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY=__REPLACE__LOG_DIR/presto/audit/archive
+#
+# Example:
+#  XAAUDIT.HDFS.IS_ENABLED=true
+#  XAAUDIT.HDFS.DESTINATION_DIRECTORY=hdfs://namenode.example.com:8020/ranger/audit/%app-type%/%time:yyyyMMdd%
+#  XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY=/var/log/presto/audit
+#  XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY=/var/log/presto/audit/archive
+#
+XAAUDIT.HDFS.IS_ENABLED=false
+XAAUDIT.HDFS.DESTINATION_DIRECTORY=hdfs://__REPLACE__NAME_NODE_HOST:8020/ranger/audit/%app-type%/%time:yyyyMMdd%
+XAAUDIT.HDFS.LOCAL_BUFFER_DIRECTORY=__REPLACE__LOG_DIR/presto/audit
+XAAUDIT.HDFS.LOCAL_ARCHIVE_DIRECTORY=__REPLACE__LOG_DIR/presto/audit/archive
+
+XAAUDIT.HDFS.DESTINTATION_FILE=%hostname%-audit.log
+XAAUDIT.HDFS.DESTINTATION_FLUSH_INTERVAL_SECONDS=900
+XAAUDIT.HDFS.DESTINTATION_ROLLOVER_INTERVAL_SECONDS=86400
+XAAUDIT.HDFS.DESTINTATION_OPEN_RETRY_INTERVAL_SECONDS=60
+XAAUDIT.HDFS.LOCAL_BUFFER_FILE=%time:yyyyMMdd-HHmm.ss%.log
+XAAUDIT.HDFS.LOCAL_BUFFER_FLUSH_INTERVAL_SECONDS=60
+XAAUDIT.HDFS.LOCAL_BUFFER_ROLLOVER_INTERVAL_SECONDS=600
+XAAUDIT.HDFS.LOCAL_ARCHIVE_MAX_FILE_COUNT=10
+
+#Solr Audit Provder
+XAAUDIT.SOLR.IS_ENABLED=false
+XAAUDIT.SOLR.MAX_QUEUE_SIZE=1
+XAAUDIT.SOLR.MAX_FLUSH_INTERVAL_MS=1000
+XAAUDIT.SOLR.SOLR_URL=http://localhost:6083/solr/ranger_audits
+
+#
+# SSL Client Certificate Information
+#
+# Example:
+# SSL_KEYSTORE_FILE_PATH=/etc/hadoop/conf/ranger-plugin-keystore.jks
+# SSL_KEYSTORE_PASSWORD=none
+# SSL_TRUSTSTORE_FILE_PATH=/etc/hadoop/conf/ranger-plugin-truststore.jks
+# SSL_TRUSTSTORE_PASSWORD=none
+#
+# You do not need use SSL between agent and security admin tool, please leave these sample value as it is.
+#
+SSL_KEYSTORE_FILE_PATH=/etc/hadoop/conf/ranger-plugin-keystore.jks
+SSL_KEYSTORE_PASSWORD=myKeyFilePassword
+SSL_TRUSTSTORE_FILE_PATH=/etc/hadoop/conf/ranger-plugin-truststore.jks
+SSL_TRUSTSTORE_PASSWORD=changeit
+
+#
+# Custom component user
+# CUSTOM_COMPONENT_USER=<custom-user>
+# keep blank if component user is default
+CUSTOM_USER=presto
+
+
+#
+# Custom component group
+# CUSTOM_COMPONENT_GROUP=<custom-group>
+# keep blank if component group is default
+CUSTOM_GROUP=hadoop
diff --git a/plugin-presto/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerSystemAccessControl.java b/plugin-presto/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerSystemAccessControl.java
new file mode 100644
index 0000000..3ab63f5
--- /dev/null
+++ b/plugin-presto/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerSystemAccessControl.java
@@ -0,0 +1,459 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.presto.authorizer;
+
+import io.prestosql.spi.connector.CatalogSchemaName;
+import io.prestosql.spi.connector.CatalogSchemaTableName;
+import io.prestosql.spi.connector.SchemaTableName;
+import io.prestosql.spi.security.AccessDeniedException;
+import io.prestosql.spi.security.Identity;
+import io.prestosql.spi.security.PrestoPrincipal;
+import io.prestosql.spi.security.Privilege;
+import io.prestosql.spi.security.SystemAccessControl;
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
+import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.service.RangerBasePlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import static java.util.Locale.ENGLISH;
+
+public class RangerSystemAccessControl
+  implements SystemAccessControl {
+
+  public static String RANGER_CONFIG_KEYTAB = "ranger.keytab";
+  public static String RANGER_CONFIG_PRINCIPAL = "ranger.principal";
+
+  public static String RANGER_PRESTO_SERVICETYPE = "presto";
+  public static String RANGER_PRESTO_APPID = "presto";
+
+  private static Logger LOG = LoggerFactory.getLogger(RangerSystemAccessControl.class);
+
+  private RangerBasePlugin rangerPlugin;
+
+  public RangerSystemAccessControl(Map<String, String> config) {
+    super();
+
+    if (config.get(RANGER_CONFIG_KEYTAB) != null && config.get(RANGER_CONFIG_PRINCIPAL) != null) {
+      String keytab = config.get(RANGER_CONFIG_KEYTAB);
+      String principal = config.get(RANGER_CONFIG_PRINCIPAL);
+
+      LOG.info("Performing kerberos login with principal " + principal + " and keytab " + keytab);
+
+      try {
+        UserGroupInformation.setConfiguration(new Configuration());
+        UserGroupInformation.loginUserFromKeytab(principal, keytab);
+      } catch (IOException ioe) {
+        LOG.error("Kerberos login failed", ioe);
+        throw new RuntimeException(ioe);
+      }
+    }
+    rangerPlugin = new RangerBasePlugin(RANGER_PRESTO_SERVICETYPE, RANGER_PRESTO_APPID);
+    rangerPlugin.init();
+    rangerPlugin.setResultProcessor(new RangerDefaultAuditHandler());
+  }
+
+  private boolean checkPermission(RangerPrestoResource resource, Identity identity, PrestoAccessType accessType) {
+    boolean ret = false;
+
+    UserGroupInformation ugi = UserGroupInformation.createRemoteUser(identity.getUser());
+
+    String[] groups = ugi != null ? ugi.getGroupNames() : null;
+
+    Set<String> userGroups = null;
+    if (groups != null && groups.length > 0) {
+      userGroups = new HashSet<>(Arrays.asList(groups));
+    }
+
+    RangerPrestoAccessRequest request = new RangerPrestoAccessRequest(
+      resource,
+      identity.getUser(),
+      userGroups,
+      accessType
+    );
+
+    RangerAccessResult result = rangerPlugin.isAccessAllowed(request);
+    if (result != null && result.getIsAllowed()) {
+      ret = true;
+    }
+
+    return ret;
+  }
+
+  @Override
+  public void checkCanSetUser(Optional<Principal> principal, String userName) {
+    if(LOG.isDebugEnabled()) {
+      LOG.debug("==> RangerSystemAccessControl.checkCanSetUser(" + userName + ")");
+    }
+
+    /*
+    if (!principal.isPresent()) {
+      //AccessDeniedException.denySetUser(principal, userName);
+    }*/
+
+    //AccessDeniedException.denySetUser(principal, userName);
+  }
+
+  @Override
+  public void checkCanSetSystemSessionProperty(Identity identity, String propertyName) {
+    if (!checkPermission(new RangerPrestoResource(), identity, PrestoAccessType.ADMIN)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanSetSystemSessionProperty denied");
+      AccessDeniedException.denySetSystemSessionProperty(propertyName);
+    }
+  }
+
+  @Override
+  public void checkCanAccessCatalog(Identity identity, String catalogName) {
+    if (!checkPermission(createResource(catalogName), identity, PrestoAccessType.SELECT)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanAccessCatalog(" + catalogName + ") denied");
+      AccessDeniedException.denyCatalogAccess(catalogName);
+    }
+  }
+
+  @Override
+  public Set<String> filterCatalogs(Identity identity, Set<String> catalogs) {
+    return catalogs;
+  }
+
+  @Override
+  public void checkCanCreateSchema(Identity identity, CatalogSchemaName schema) {
+    if (!checkPermission(createResource(schema.getCatalogName(), schema.getSchemaName()), identity, PrestoAccessType.CREATE)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanCreateSchema(" + schema.getSchemaName() + ") denied");
+      AccessDeniedException.denyCreateSchema(schema.getSchemaName());
+    }
+  }
+
+  @Override
+  public void checkCanDropSchema(Identity identity, CatalogSchemaName schema) {
+    if (!checkPermission(createResource(schema.getCatalogName(), schema.getSchemaName()), identity, PrestoAccessType.DROP)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanDropSchema(" + schema.getSchemaName() + ") denied");
+      AccessDeniedException.denyDropSchema(schema.getSchemaName());
+    }
+  }
+
+  @Override
+  public void checkCanRenameSchema(Identity identity, CatalogSchemaName schema, String newSchemaName) {
+    RangerPrestoResource res = createResource(schema.getCatalogName(), schema.getSchemaName());
+    if (!checkPermission(res, identity, PrestoAccessType.ALTER)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanRenameSchema(" + schema.getSchemaName() + ") denied");
+      AccessDeniedException.denyRenameSchema(schema.getSchemaName(), newSchemaName);
+    }
+  }
+
+  @Override
+  public void checkCanShowSchemas(Identity identity, String catalogName) {
+    if (!checkPermission(createResource(catalogName), identity, PrestoAccessType.SELECT)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanShowSchemas(" + catalogName + ") denied");
+      AccessDeniedException.denyShowSchemas(catalogName);
+    }
+  }
+
+  @Override
+  public Set<String> filterSchemas(Identity identity, String catalogName, Set<String> schemaNames) {
+    LOG.debug("==> RangerSystemAccessControl.filterSchemas(" + catalogName + ")");
+    return schemaNames;
+  }
+
+  @Override
+  public void checkCanCreateTable(Identity identity, CatalogSchemaTableName table) {
+    if (!checkPermission(createResource(table), identity, PrestoAccessType.CREATE)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanCreateTable(" + table.getSchemaTableName().getTableName() + ") denied");
+      AccessDeniedException.denyCreateTable(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanDropTable(Identity identity, CatalogSchemaTableName table) {
+    if (!checkPermission(createResource(table), identity, PrestoAccessType.DROP)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanDropTable(" + table.getSchemaTableName().getTableName() + ") denied");
+      AccessDeniedException.denyDropTable(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanRenameTable(Identity identity, CatalogSchemaTableName table, CatalogSchemaTableName newTable) {
+    RangerPrestoResource res = createResource(table);
+    if (!checkPermission(res, identity, PrestoAccessType.ALTER)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanRenameTable(" + table.getSchemaTableName().getTableName() + ") denied");
+      AccessDeniedException.denyRenameTable(table.getSchemaTableName().getTableName(), newTable.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanShowTablesMetadata(Identity identity, CatalogSchemaName schema) {
+    if (!checkPermission(createResource(schema.getCatalogName(), schema.getSchemaName()), identity, PrestoAccessType.SELECT)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanShowTablesMetadata(" + schema.getSchemaName() + ") denied");
+      AccessDeniedException.denyShowTablesMetadata(schema.getSchemaName());
+    }
+  }
+
+  @Override
+  public Set<SchemaTableName> filterTables(Identity identity, String catalogName, Set<SchemaTableName> tableNames) {
+    LOG.debug("==> RangerSystemAccessControl.filterTables(" + catalogName + ")");
+    return tableNames;
+  }
+
+  @Override
+  public void checkCanAddColumn(Identity identity, CatalogSchemaTableName table) {
+    RangerPrestoResource res = createResource(table);
+    if (!checkPermission(res, identity, PrestoAccessType.ALTER)) {
+      AccessDeniedException.denyAddColumn(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanDropColumn(Identity identity, CatalogSchemaTableName table) {
+    RangerPrestoResource res = createResource(table);
+    if (!checkPermission(res, identity, PrestoAccessType.ALTER)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanDropColumn(" + table.getSchemaTableName().getTableName() + ") denied");
+      AccessDeniedException.denyDropColumn(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanRenameColumn(Identity identity, CatalogSchemaTableName table) {
+    RangerPrestoResource res = createResource(table);
+    if (!checkPermission(res, identity, PrestoAccessType.ALTER)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanRenameColumn(" + table.getSchemaTableName().getTableName() + ") denied");
+      AccessDeniedException.denyRenameColumn(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanSelectFromColumns(Identity identity, CatalogSchemaTableName table, Set<String> columns) {
+    for (RangerPrestoResource res : createResource(table, columns)) {
+      if (!checkPermission(res, identity, PrestoAccessType.SELECT)) {
+        LOG.info("==> RangerSystemAccessControl.checkCanSelectFromColumns(" + table.getSchemaTableName().getTableName() + ") denied");
+        AccessDeniedException.denySelectColumns(table.getSchemaTableName().getTableName(), columns);
+      }
+    }
+  }
+
+  @Override
+  public void checkCanInsertIntoTable(Identity identity, CatalogSchemaTableName table) {
+    RangerPrestoResource res = createResource(table);
+    if (!checkPermission(res, identity, PrestoAccessType.INSERT)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanInsertIntoTable(" + table.getSchemaTableName().getTableName() + ") denied");
+      AccessDeniedException.denyInsertTable(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanDeleteFromTable(Identity identity, CatalogSchemaTableName table) {
+    if (!checkPermission(createResource(table), identity, PrestoAccessType.DELETE)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanDeleteFromTable(" + table.getSchemaTableName().getTableName() + ") denied");
+      AccessDeniedException.denyDeleteTable(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanCreateView(Identity identity, CatalogSchemaTableName view) {
+    if (!checkPermission(createResource(view), identity, PrestoAccessType.CREATE)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanCreateView(" + view.getSchemaTableName().getTableName() + ") denied");
+      AccessDeniedException.denyCreateView(view.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanDropView(Identity identity, CatalogSchemaTableName view) {
+    if (!checkPermission(createResource(view), identity, PrestoAccessType.DROP)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanDropView(" + view.getSchemaTableName().getTableName() + ") denied");
+      AccessDeniedException.denyCreateView(view.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanCreateViewWithSelectFromColumns(Identity identity, CatalogSchemaTableName table, Set<String> columns) {
+    for (RangerPrestoResource res : createResource(table, columns)) {
+      if (!checkPermission(res, identity, PrestoAccessType.CREATE)) {
+        LOG.info("==> RangerSystemAccessControl.checkCanDropView(" + table.getSchemaTableName().getTableName() + ") denied");
+        AccessDeniedException.denyCreateViewWithSelect(table.getSchemaTableName().getTableName(), identity);
+      }
+    }
+  }
+
+  @Override
+  public void checkCanSetCatalogSessionProperty(Identity identity, String catalogName, String propertyName) {
+    if (!checkPermission(createResource(catalogName), identity, PrestoAccessType.ADMIN)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanSetSystemSessionProperty(" + catalogName + ") denied");
+      AccessDeniedException.denySetCatalogSessionProperty(catalogName, propertyName);
+    }
+  }
+
+  @Override
+  public void checkCanGrantTablePrivilege(Identity identity, Privilege privilege, CatalogSchemaTableName table, PrestoPrincipal grantee, boolean withGrantOption) {
+    if (!checkPermission(createResource(table), identity, PrestoAccessType.ADMIN)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanGrantTablePrivilege(" + table + ") denied");
+      AccessDeniedException.denyGrantTablePrivilege(privilege.toString(), table.toString());
+    }
+  }
+
+  @Override
+  public void checkCanRevokeTablePrivilege(Identity identity, Privilege privilege, CatalogSchemaTableName table, PrestoPrincipal revokee, boolean grantOptionFor) {
+    if (!checkPermission(createResource(table), identity, PrestoAccessType.ADMIN)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanRevokeTablePrivilege(" + table + ") denied");
+      AccessDeniedException.denyRevokeTablePrivilege(privilege.toString(), table.toString());
+    }
+  }
+
+  @Override
+  public void checkCanShowRoles(Identity identity, String catalogName) {
+    if (!checkPermission(createResource(catalogName), identity, PrestoAccessType.ADMIN)) {
+      LOG.info("==> RangerSystemAccessControl.checkCanShowRoles(" + catalogName + ") denied");
+      AccessDeniedException.denyShowRoles(catalogName);
+    }
+  }
+
+  private static RangerPrestoResource createResource(CatalogSchemaName catalogSchemaName) {
+    return createResource(catalogSchemaName.getCatalogName(), catalogSchemaName.getSchemaName());
+  }
+
+  private static RangerPrestoResource createResource(CatalogSchemaTableName catalogSchemaTableName) {
+    return createResource(catalogSchemaTableName.getCatalogName(),
+      catalogSchemaTableName.getSchemaTableName().getSchemaName(),
+      catalogSchemaTableName.getSchemaTableName().getTableName());
+  }
+
+  private static RangerPrestoResource createResource(String catalogName) {
+    return new RangerPrestoResource(catalogName, Optional.empty(), Optional.empty());
+  }
+
+  private static RangerPrestoResource createResource(String catalogName, String schemaName) {
+    return new RangerPrestoResource(catalogName, Optional.of(schemaName), Optional.empty());
+  }
+
+  private static RangerPrestoResource createResource(String catalogName, String schemaName, final String tableName) {
+    return new RangerPrestoResource(catalogName, Optional.of(schemaName), Optional.of(tableName));
+  }
+
+  private static RangerPrestoResource createResource(String catalogName, String schemaName, final String tableName, final Optional<String> column) {
+    return new RangerPrestoResource(catalogName, Optional.of(schemaName), Optional.of(tableName), column);
+  }
+
+  private static List<RangerPrestoResource> createResource(CatalogSchemaTableName table, Set<String> columns) {
+    List<RangerPrestoResource> colRequests = new ArrayList<>();
+
+    if (columns.size() > 0) {
+      for (String column : columns) {
+        RangerPrestoResource rangerPrestoResource = createResource(table.getCatalogName(),
+          table.getSchemaTableName().getSchemaName(),
+          table.getSchemaTableName().getTableName(), Optional.of(column));
+        colRequests.add(rangerPrestoResource);
+      }
+    } else {
+      colRequests.add(createResource(table.getCatalogName(),
+        table.getSchemaTableName().getSchemaName(),
+        table.getSchemaTableName().getTableName(), Optional.empty()));
+    }
+    return colRequests;
+  }
+}
+
+class RangerPrestoResource
+  extends RangerAccessResourceImpl {
+
+
+  public static final String KEY_CATALOG = "catalog";
+  public static final String KEY_SCHEMA = "schema";
+  public static final String KEY_TABLE = "table";
+  public static final String KEY_COLUMN = "column";
+
+  public RangerPrestoResource() {}
+
+  public RangerPrestoResource(String catalogName, Optional<String> schema, Optional<String> table) {
+    setValue(KEY_CATALOG, catalogName);
+    if (schema.isPresent()) {
+      setValue(KEY_SCHEMA, schema.get());
+    }
+    if (table.isPresent()) {
+      setValue(KEY_TABLE, table.get());
+    }
+  }
+
+  public RangerPrestoResource(String catalogName, Optional<String> schema, Optional<String> table, Optional<String> column) {
+    setValue(KEY_CATALOG, catalogName);
+    if (schema.isPresent()) {
+      setValue(KEY_SCHEMA, schema.get());
+    }
+    if (table.isPresent()) {
+      setValue(KEY_TABLE, table.get());
+    }
+    if (column.isPresent()) {
+      setValue(KEY_COLUMN, column.get());
+    }
+  }
+
+  public String getCatalogName() {
+    return (String) getValue(KEY_CATALOG);
+  }
+
+  public String getTable() {
+    return (String) getValue(KEY_TABLE);
+  }
+
+  public String getCatalog() {
+    return (String) getValue(KEY_CATALOG);
+  }
+
+  public String getSchema() { return (String) getValue(KEY_SCHEMA); }
+
+  public Optional<SchemaTableName> getSchemaTable() {
+    final String schema = getSchema();
+    if (StringUtils.isNotEmpty(schema)) {
+      return Optional.of(new SchemaTableName(schema, Optional.ofNullable(getTable()).orElse("*")));
+    }
+    return Optional.empty();
+  }
+}
+
+class RangerPrestoAccessRequest
+  extends RangerAccessRequestImpl {
+  public RangerPrestoAccessRequest(RangerPrestoResource resource,
+                                   String user,
+                                   Set<String> userGroups,
+                                   PrestoAccessType prestoAccessType)
+
+  {
+    super(resource,
+      prestoAccessType == PrestoAccessType.USE ? RangerPolicyEngine.ANY_ACCESS :
+        prestoAccessType == PrestoAccessType.ADMIN ? RangerPolicyEngine.ADMIN_ACCESS :
+          prestoAccessType.name().toLowerCase(ENGLISH), user,
+      userGroups);
+  }
+}
+
+enum PrestoAccessType {
+  CREATE, DROP, SELECT, INSERT, DELETE, USE, ALTER, ALL, ADMIN;
+}
\ No newline at end of file
diff --git a/plugin-presto/src/main/java/org/apache/ranger/services/presto/RangerServicePresto.java b/plugin-presto/src/main/java/org/apache/ranger/services/presto/RangerServicePresto.java
new file mode 100644
index 0000000..f41b2c8
--- /dev/null
+++ b/plugin-presto/src/main/java/org/apache/ranger/services/presto/RangerServicePresto.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.services.presto;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.client.HadoopException;
+import org.apache.ranger.plugin.service.RangerBaseService;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.apache.ranger.services.presto.client.PrestoResourceManager;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class RangerServicePresto extends RangerBaseService {
+  private static final Log LOG = LogFactory.getLog(RangerServicePresto.class);
+
+  @Override
+  public Map<String, Object> validateConfig() throws Exception {
+    Map<String, Object> ret = new HashMap<String, Object>();
+    String serviceName = getServiceName();
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("RangerServicePresto.validateConfig(): Service: " +
+        serviceName);
+    }
+
+    if (configs != null) {
+      try {
+        ret = PrestoResourceManager.connectionTest(serviceName, configs);
+      } catch (HadoopException he) {
+        LOG.error("<== RangerServicePresto.validateConfig Error:" + he);
+        throw he;
+      }
+    }
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("RangerServicePresto.validateConfig(): Response: " +
+        ret);
+    }
+    return ret;
+  }
+
+  @Override
+  public List<String> lookupResource(ResourceLookupContext context) throws Exception {
+
+    List<String> ret 		   = new ArrayList<String>();
+    String 	serviceName  	   = getServiceName();
+    String	serviceType		   = getServiceType();
+    Map<String,String> configs = getConfigs();
+    if(LOG.isDebugEnabled()) {
+      LOG.debug("==> RangerServiceHive.lookupResource Context: (" + context + ")");
+    }
+    if (context != null) {
+      try {
+        ret  = PrestoResourceManager.getPrestoResources(serviceName, serviceType, configs,context);
+      } catch (Exception e) {
+        LOG.error( "<==RangerServicePresto.lookupResource Error : " + e);
+        throw e;
+      }
+    }
+    if(LOG.isDebugEnabled()) {
+      LOG.debug("<== RangerServicePresto.lookupResource Response: (" + ret + ")");
+    }
+    return ret;
+  }
+
+}
diff --git a/plugin-presto/src/main/java/org/apache/ranger/services/presto/client/PrestoClient.java b/plugin-presto/src/main/java/org/apache/ranger/services/presto/client/PrestoClient.java
new file mode 100644
index 0000000..37c2346
--- /dev/null
+++ b/plugin-presto/src/main/java/org/apache/ranger/services/presto/client/PrestoClient.java
@@ -0,0 +1,556 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.services.presto.client;
+
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.client.BaseClient;
+import org.apache.ranger.plugin.client.HadoopConfigHolder;
+import org.apache.ranger.plugin.client.HadoopException;
+
+import javax.security.auth.Subject;
+import java.io.Closeable;
+import java.security.PrivilegedAction;
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLTimeoutException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+public class PrestoClient extends BaseClient implements Closeable {
+  public static final String PRESTO_USER_NAME_PROP = "user";
+  public static final String PRESTO_PASSWORD_PROP = "password";
+
+  private static final Log LOG = LogFactory.getLog(PrestoClient.class);
+
+  private static final String ERR_MSG = "You can still save the repository and start creating "
+    + "policies, but you would not be able to use autocomplete for "
+    + "resource names. Check ranger_admin.log for more info.";
+
+  private Connection con;
+
+  public PrestoClient(String serviceName) throws Exception {
+    super(serviceName, null);
+    init();
+  }
+
+  public PrestoClient(String serviceName, Map<String, String> properties) throws Exception {
+    super(serviceName, properties);
+    init();
+  }
+
+  private void init() throws Exception {
+    Subject.doAs(getLoginSubject(), new PrivilegedAction<Void>() {
+      public Void run() {
+        initConnection();
+        return null;
+      }
+    });
+  }
+
+  private void initConnection() {
+    Properties prop = getConfigHolder().getRangerSection();
+    String driverClassName = prop.getProperty("jdbc.driverClassName");
+    String url = prop.getProperty("jdbc.url");
+
+    Properties prestoProperties = new Properties();
+    prestoProperties.put(PRESTO_USER_NAME_PROP, prop.getProperty(HadoopConfigHolder.RANGER_LOGIN_USER_NAME_PROP));
+    prestoProperties.put(PRESTO_PASSWORD_PROP, prop.getProperty(HadoopConfigHolder.RANGER_LOGIN_PASSWORD));
+
+    if (driverClassName != null) {
+      try {
+        Driver driver = (Driver) Class.forName(driverClassName).newInstance();
+        DriverManager.registerDriver(driver);
+      } catch (SQLException e) {
+        String msgDesc = "initConnection: Caught SQLException while registering"
+          + " the Presto driver.";
+        HadoopException hdpException = new HadoopException(msgDesc, e);
+        hdpException.generateResponseDataMap(false, getMessage(e),
+          msgDesc + ERR_MSG, null, null);
+        throw hdpException;
+      } catch (IllegalAccessException ilae) {
+        String msgDesc = "initConnection: Class or its nullary constructor might not accessible.";
+        HadoopException hdpException = new HadoopException(msgDesc, ilae);
+        hdpException.generateResponseDataMap(false, getMessage(ilae),
+          msgDesc + ERR_MSG, null, null);
+        throw hdpException;
+      } catch (InstantiationException ie) {
+        String msgDesc = "initConnection: Class may not have its nullary constructor or "
+          + "may be the instantiation fails for some other reason.";
+        HadoopException hdpException = new HadoopException(msgDesc, ie);
+        hdpException.generateResponseDataMap(false, getMessage(ie),
+          msgDesc + ERR_MSG, null, null);
+        throw hdpException;
+      } catch (ExceptionInInitializerError eie) {
+        String msgDesc = "initConnection: Got ExceptionInInitializerError, "
+          + "The initialization provoked by this method fails.";
+        HadoopException hdpException = new HadoopException(msgDesc,
+          eie);
+        hdpException.generateResponseDataMap(false, getMessage(eie),
+          msgDesc + ERR_MSG, null, null);
+        throw hdpException;
+      } catch (SecurityException se) {
+        String msgDesc = "initConnection: unable to initiate connection to Presto instance,"
+          + " The caller's class loader is not the same as or an ancestor "
+          + "of the class loader for the current class and invocation of "
+          + "s.checkPackageAccess() denies access to the package of this class.";
+        HadoopException hdpException = new HadoopException(msgDesc, se);
+        hdpException.generateResponseDataMap(false, getMessage(se),
+          msgDesc + ERR_MSG, null, null);
+        throw hdpException;
+      } catch (Throwable t) {
+        String msgDesc = "initConnection: Unable to connect to Presto instance, "
+          + "please provide valid value of field : {jdbc.driverClassName}.";
+        HadoopException hdpException = new HadoopException(msgDesc, t);
+        hdpException.generateResponseDataMap(false, getMessage(t),
+          msgDesc + ERR_MSG, null, null);
+        throw hdpException;
+      }
+    }
+
+    try {
+      con = DriverManager.getConnection(url, prestoProperties);
+    } catch (SQLException e) {
+      String msgDesc = "Unable to connect to Presto instance.";
+      HadoopException hdpException = new HadoopException(msgDesc, e);
+      hdpException.generateResponseDataMap(false, getMessage(e),
+        msgDesc + ERR_MSG, null, null);
+      throw hdpException;
+    } catch (SecurityException se) {
+      String msgDesc = "Unable to connect to Presto instance.";
+      HadoopException hdpException = new HadoopException(msgDesc, se);
+      hdpException.generateResponseDataMap(false, getMessage(se),
+        msgDesc + ERR_MSG, null, null);
+      throw hdpException;
+    } catch (Throwable t) {
+      String msgDesc = "initConnection: Unable to connect to Presto instance, ";
+      HadoopException hdpException = new HadoopException(msgDesc, t);
+      hdpException.generateResponseDataMap(false, getMessage(t),
+        msgDesc + ERR_MSG, null, null);
+      throw hdpException;
+    }
+
+  }
+
+  private List<String> getCatalogs(String needle, List<String> catalogs) throws HadoopException {
+    List<String> ret = new ArrayList<>();
+    if (con != null) {
+      Statement stat = null;
+      ResultSet rs = null;
+      String sql = "SHOW CATALOGS";
+
+      try {
+        if (needle != null && !needle.isEmpty() && !needle.equals("*")) {
+          // Cannot use a prepared statement for this as presto does not support that
+          sql += " LIKE '" + StringEscapeUtils.escapeSql(needle) + "%'";
+        }
+        stat = con.createStatement();
+        rs = stat.executeQuery(sql);
+        while (rs.next()) {
+          String catalogName = rs.getString(1);
+          if (catalogs != null && catalogs.contains(catalogName)) {
+            continue;
+          }
+          ret.add(catalogName);
+        }
+      } catch (SQLTimeoutException sqlt) {
+        String msgDesc = "Time Out, Unable to execute SQL [" + sql
+          + "].";
+        HadoopException hdpException = new HadoopException(msgDesc,
+          sqlt);
+        hdpException.generateResponseDataMap(false, getMessage(sqlt),
+          msgDesc + ERR_MSG, null, null);
+      } catch (SQLException se) {
+        String msg = "Unable to execute SQL [" + sql + "]. ";
+        HadoopException he = new HadoopException(msg, se);
+        he.generateResponseDataMap(false, getMessage(se), msg + ERR_MSG,
+          null, null);
+        throw he;
+      } finally {
+        close(rs);
+        close(stat);
+      }
+    }
+    return ret;
+  }
+
+  public List<String> getCatalogList(String needle, final List<String> catalogs) throws HadoopException {
+    final String ndl = needle;
+    final List<String> catList = catalogs;
+
+    List<String> dbs = Subject.doAs(getLoginSubject(), new PrivilegedAction<List<String>>() {
+      @Override
+      public List<String> run() {
+        List<String> ret = null;
+        try {
+          ret = getCatalogs(ndl, catList);
+        } catch (HadoopException he) {
+          LOG.error("<== PrestoClient getCatalogList() :Unable to get the Database List", he);
+          throw he;
+        }
+        return ret;
+      }
+    });
+
+    return dbs;
+  }
+
+  private List<String> getSchemas(String needle, List<String> catalogs, List<String> schemas) throws HadoopException {
+    List<String> ret = new ArrayList<>();
+    if (con != null) {
+      Statement stat = null;
+      ResultSet rs = null;
+      String sql = null;
+
+      try {
+        if (catalogs != null && !catalogs.isEmpty()) {
+          for (String catalog : catalogs) {
+            sql = "SHOW SCHEMAS FROM \"" + StringEscapeUtils.escapeSql(catalog) + "\"";
+
+            try {
+              if (needle != null && !needle.isEmpty() && !needle.equals("*")) {
+                sql += " LIKE '" + StringEscapeUtils.escapeSql(needle) + "%'";
+              }
+              stat = con.createStatement();
+              rs = stat.executeQuery(sql);
+              while (rs.next()) {
+                String schema = rs.getString(1);
+                if (schemas != null && schemas.contains(schema)) {
+                  continue;
+                }
+                ret.add(schema);
+              }
+            } finally {
+              close(rs);
+              close(stat);
+              rs = null;
+              stat = null;
+            }
+          }
+        }
+      } catch (SQLTimeoutException sqlt) {
+        String msgDesc = "Time Out, Unable to execute SQL [" + sql
+          + "].";
+        HadoopException hdpException = new HadoopException(msgDesc,
+          sqlt);
+        hdpException.generateResponseDataMap(false, getMessage(sqlt),
+          msgDesc + ERR_MSG, null, null);
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("<== PrestoClient.getSchemas() Error : ", sqlt);
+        }
+        throw hdpException;
+      } catch (SQLException sqle) {
+        String msgDesc = "Unable to execute SQL [" + sql + "].";
+        HadoopException hdpException = new HadoopException(msgDesc,
+          sqle);
+        hdpException.generateResponseDataMap(false, getMessage(sqle),
+          msgDesc + ERR_MSG, null, null);
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("<== PrestoClient.getSchemas() Error : ", sqle);
+        }
+        throw hdpException;
+      }
+    }
+
+    return ret;
+  }
+
+  public List<String> getSchemaList(String needle, List<String> catalogs, List<String> schemas) throws HadoopException {
+    final String ndl = needle;
+    final List<String> cats = catalogs;
+    final List<String> shms = schemas;
+
+    List<String> schemaList = Subject.doAs(getLoginSubject(), new PrivilegedAction<List<String>>() {
+      @Override
+      public List<String> run() {
+        List<String> ret = null;
+        try {
+          ret = getSchemas(ndl, cats, shms);
+        } catch (HadoopException he) {
+          LOG.error("<== PrestoClient getSchemaList() :Unable to get the Schema List", he);
+        }
+        return ret;
+      }
+    });
+
+    return schemaList;
+  }
+
+  private List<String> getTables(String needle, List<String> catalogs, List<String> schemas, List<String> tables) throws HadoopException {
+    List<String> ret = new ArrayList<>();
+    if (con != null) {
+      Statement stat = null;
+      ResultSet rs = null;
+      String sql = null;
+
+      if (catalogs != null && !catalogs.isEmpty()
+        && schemas != null && !schemas.isEmpty()) {
+        try {
+          for (String catalog : catalogs) {
+            for (String schema : schemas) {
+              sql = "SHOW tables FROM \"" + StringEscapeUtils.escapeSql(catalog) + "\".\"" + StringEscapeUtils.escapeSql(schema) + "\"";
+              try {
+                if (needle != null && !needle.isEmpty() && !needle.equals("*")) {
+                  sql += " LIKE '" + StringEscapeUtils.escapeSql(needle) + "%'";
+                }
+                stat = con.createStatement();
+                rs = stat.executeQuery(sql);
+                while (rs.next()) {
+                  String table = rs.getString(1);
+                  if (tables != null && tables.contains(table)) {
+                    continue;
+                  }
+                  ret.add(table);
+                }
+              } finally {
+                close(rs);
+                close(stat);
+                rs = null;
+                stat = null;
+              }
+            }
+          }
+        } catch (SQLTimeoutException sqlt) {
+          String msgDesc = "Time Out, Unable to execute SQL [" + sql
+            + "].";
+          HadoopException hdpException = new HadoopException(msgDesc,
+            sqlt);
+          hdpException.generateResponseDataMap(false, getMessage(sqlt),
+            msgDesc + ERR_MSG, null, null);
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("<== PrestoClient.getTables() Error : ", sqlt);
+          }
+          throw hdpException;
+        } catch (SQLException sqle) {
+          String msgDesc = "Unable to execute SQL [" + sql + "].";
+          HadoopException hdpException = new HadoopException(msgDesc,
+            sqle);
+          hdpException.generateResponseDataMap(false, getMessage(sqle),
+            msgDesc + ERR_MSG, null, null);
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("<== PrestoClient.getTables() Error : ", sqle);
+          }
+          throw hdpException;
+        }
+      }
+    }
+    return ret;
+  }
+
+  public List<String> getTableList(String needle, List<String> catalogs, List<String> schemas, List<String> tables) throws HadoopException {
+    final String ndl = needle;
+    final List<String> cats = catalogs;
+    final List<String> shms = schemas;
+    final List<String> tbls = tables;
+
+    List<String> tableList = Subject.doAs(getLoginSubject(), new PrivilegedAction<List<String>>() {
+      @Override
+      public List<String> run() {
+        List<String> ret = null;
+        try {
+          ret = getTables(ndl, cats, shms, tbls);
+        } catch (HadoopException he) {
+          LOG.error("<== PrestoClient getTableList() :Unable to get the Column List", he);
+          throw he;
+        }
+        return ret;
+      }
+    });
+
+    return tableList;
+  }
+
+  private List<String> getColumns(String needle, List<String> catalogs, List<String> schemas, List<String> tables, List<String> columns) throws HadoopException {
+    List<String> ret = new ArrayList<>();
+    if (con != null) {
+      String regex = null;
+      ResultSet rs = null;
+      String sql = null;
+      Statement stat = null;
+
+      if (needle != null && !needle.isEmpty()) {
+        regex = needle;
+      }
+
+      if (catalogs != null && !catalogs.isEmpty()
+        && schemas != null && !schemas.isEmpty()
+        && tables != null && !tables.isEmpty()) {
+        try {
+          for (String catalog : catalogs) {
+            for (String schema : schemas) {
+              for (String table : tables) {
+                sql = "SHOW COLUMNS FROM \"" + StringEscapeUtils.escapeSql(catalog) + "\"." +
+                  "\"" + StringEscapeUtils.escapeSql(schema) + "\"." +
+                  "\"" + StringEscapeUtils.escapeSql(table) + "\"";
+
+                try {
+                  stat = con.createStatement();
+                  rs = stat.executeQuery(sql);
+                  while (rs.next()) {
+                    String column = rs.getString(1);
+                    if (columns != null && columns.contains(column)) {
+                      continue;
+                    }
+                    if (regex == null) {
+                      ret.add(column);
+                    } else if (FilenameUtils.wildcardMatch(column, regex)) {
+                      ret.add(column);
+                    }
+                  }
+                } finally {
+                  close(rs);
+                  close(stat);
+                  stat = null;
+                  rs = null;
+                }
+              }
+            }
+          }
+        } catch (SQLTimeoutException sqlt) {
+          String msgDesc = "Time Out, Unable to execute SQL [" + sql
+            + "].";
+          HadoopException hdpException = new HadoopException(msgDesc,
+            sqlt);
+          hdpException.generateResponseDataMap(false, getMessage(sqlt),
+            msgDesc + ERR_MSG, null, null);
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("<== PrestoClient.getColumns() Error : ", sqlt);
+          }
+          throw hdpException;
+        } catch (SQLException sqle) {
+          String msgDesc = "Unable to execute SQL [" + sql + "].";
+          HadoopException hdpException = new HadoopException(msgDesc,
+            sqle);
+          hdpException.generateResponseDataMap(false, getMessage(sqle),
+            msgDesc + ERR_MSG, null, null);
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("<== PrestoClient.getColumns() Error : ", sqle);
+          }
+          throw hdpException;
+        }
+      }
+    }
+    return ret;
+  }
+
+  public List<String> getColumnList(String needle, List<String> catalogs, List<String> schemas, List<String> tables, List<String> columns) throws HadoopException {
+    final String ndl = needle;
+    final List<String> cats = catalogs;
+    final List<String> shms = schemas;
+    final List<String> tbls = tables;
+    final List<String> cols = columns;
+
+    List<String> columnList = Subject.doAs(getLoginSubject(), new PrivilegedAction<List<String>>() {
+      @Override
+      public List<String> run() {
+        List<String> ret = null;
+        try {
+          ret = getColumns(ndl, cats, shms, tbls, cols);
+        } catch (HadoopException he) {
+          LOG.error("<== PrestoClient getColumnList() :Unable to get the Column List", he);
+          throw he;
+        }
+        return ret;
+      }
+    });
+    return columnList;
+  }
+
+  public static Map<String, Object> connectionTest(String serviceName,
+                                                   Map<String, String> connectionProperties)
+    throws Exception {
+    PrestoClient client = null;
+    Map<String, Object> resp = new HashMap<String, Object>();
+
+    boolean status = false;
+
+    List<String> testResult = null;
+
+    try {
+      client = new PrestoClient(serviceName, connectionProperties);
+      if (client != null) {
+        testResult = client.getCatalogList("*", null);
+        if (testResult != null && testResult.size() != 0) {
+          status = true;
+        }
+      }
+
+      if (status) {
+        String msg = "Connection test succesful";
+        generateResponseDataMap(status, msg, msg, null, null, resp);
+      }
+    } catch (Exception e) {
+      throw e;
+    } finally {
+      if (client != null) {
+        client.close();
+      }
+    }
+
+    return resp;
+  }
+
+  public void close() {
+    Subject.doAs(getLoginSubject(), new PrivilegedAction<Void>() {
+      public Void run() {
+        close(con);
+        return null;
+      }
+    });
+  }
+
+  private void close(Connection con) {
+    try {
+      if (con != null) {
+        con.close();
+      }
+    } catch (SQLException e) {
+      LOG.error("Unable to close Presto SQL connection", e);
+    }
+  }
+
+  public void close(Statement stat) {
+    try {
+      if (stat != null) {
+        stat.close();
+      }
+    } catch (SQLException e) {
+      LOG.error("Unable to close SQL statement", e);
+    }
+  }
+
+  public void close(ResultSet rs) {
+    try {
+      if (rs != null) {
+        rs.close();
+      }
+    } catch (SQLException e) {
+      LOG.error("Unable to close ResultSet", e);
+    }
+  }
+}
diff --git a/plugin-presto/src/main/java/org/apache/ranger/services/presto/client/PrestoConnectionManager.java b/plugin-presto/src/main/java/org/apache/ranger/services/presto/client/PrestoConnectionManager.java
new file mode 100644
index 0000000..4a642ea
--- /dev/null
+++ b/plugin-presto/src/main/java/org/apache/ranger/services/presto/client/PrestoConnectionManager.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.services.presto.client;
+
+import org.apache.log4j.Logger;
+import org.apache.ranger.plugin.util.TimedEventUtil;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+public class PrestoConnectionManager {
+  private static final Logger LOG = Logger.getLogger(PrestoConnectionManager.class);
+
+  protected ConcurrentMap<String, PrestoClient> prestoConnectionCache;
+  protected ConcurrentMap<String, Boolean> repoConnectStatusMap;
+
+  public PrestoConnectionManager() {
+    prestoConnectionCache = new ConcurrentHashMap<>();
+    repoConnectStatusMap = new ConcurrentHashMap<>();
+  }
+
+  public PrestoClient getPrestoConnection(final String serviceName, final String serviceType, final Map<String, String> configs) {
+    PrestoClient prestoClient = null;
+
+    if (serviceType != null) {
+      prestoClient = prestoConnectionCache.get(serviceName);
+      if (prestoClient == null) {
+        if (configs != null) {
+          final Callable<PrestoClient> connectPresto = new Callable<PrestoClient>() {
+            @Override
+            public PrestoClient call() throws Exception {
+              return new PrestoClient(serviceName, configs);
+            }
+          };
+          try {
+            prestoClient = TimedEventUtil.timedTask(connectPresto, 5, TimeUnit.SECONDS);
+          } catch (Exception e) {
+            LOG.error("Error connecting to Presto repository: " +
+            serviceName + " using config: " + configs, e);
+          }
+
+          PrestoClient oldClient = null;
+          if (prestoClient != null) {
+            oldClient = prestoConnectionCache.putIfAbsent(serviceName, prestoClient);
+          } else {
+            oldClient = prestoConnectionCache.get(serviceName);
+          }
+
+          if (oldClient != null) {
+            if (prestoClient != null) {
+              prestoClient.close();
+            }
+            prestoClient = oldClient;
+          }
+          repoConnectStatusMap.put(serviceName, true);
+        } else {
+          LOG.error("Connection Config not defined for asset :"
+            + serviceName, new Throwable());
+        }
+      } else {
+        try {
+          prestoClient.getCatalogList("*", null);
+        } catch (Exception e) {
+          prestoConnectionCache.remove(serviceName);
+          prestoClient.close();
+          prestoClient = getPrestoConnection(serviceName, serviceType, configs);
+        }
+      }
+    } else {
+      LOG.error("Asset not found with name " + serviceName, new Throwable());
+    }
+    return prestoClient;
+  }
+}
diff --git a/plugin-presto/src/main/java/org/apache/ranger/services/presto/client/PrestoResourceManager.java b/plugin-presto/src/main/java/org/apache/ranger/services/presto/client/PrestoResourceManager.java
new file mode 100644
index 0000000..008bf0f
--- /dev/null
+++ b/plugin-presto/src/main/java/org/apache/ranger/services/presto/client/PrestoResourceManager.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.services.presto.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.apache.ranger.plugin.util.TimedEventUtil;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+public class PrestoResourceManager {
+  private static final Log LOG = LogFactory.getLog(PrestoResourceManager.class);
+
+  private static final String  CATALOG 	  = "catalog";
+  private static final String  SCHEMA     = "schema";
+  private static final String  TABLE	 	  = "table";
+  private static final String  COLUMN	 	  = "column";
+
+
+  public static Map<String, Object> connectionTest(String serviceName, Map<String, String> configs) throws Exception {
+    Map<String, Object> ret = null;
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("==> PrestoResourceMgr.connectionTest ServiceName: " + serviceName + "Configs" + configs);
+    }
+
+    try {
+      ret = PrestoClient.connectionTest(serviceName, configs);
+    } catch (Exception e) {
+      LOG.error("<== PrestoResourceManager.connectionTest Error: " + e);
+      throw e;
+    }
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("<== PrestoResourceManager.connectionTest Result : " + ret);
+    }
+
+    return ret;
+  }
+
+  public static List<String> getPrestoResources(String serviceName, String serviceType, Map<String, String> configs, ResourceLookupContext context) throws Exception {
+
+    String userInput = context.getUserInput();
+    String resource = context.getResourceName();
+    Map<String, List<String>> resourceMap = context.getResources();
+    List<String> resultList = null;
+    List<String> catalogList = null;
+    List<String> schemaList = null;
+    List<String> tableList = null;
+    List<String> columnList = null;
+    String catalogName = null;
+    String schemaName = null;
+    String tableName = null;
+    String columnName = null;
+
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("<== PrestoResourceMgr.getPrestoResources()  UserInput: \"" + userInput + "\" resource : " + resource + " resourceMap: " + resourceMap);
+    }
+
+    if (userInput != null && resource != null) {
+      if (resourceMap != null && !resourceMap.isEmpty()) {
+        catalogList = resourceMap.get(CATALOG);
+        schemaList = resourceMap.get(SCHEMA);
+        tableList = resourceMap.get(TABLE);
+        columnList = resourceMap.get(COLUMN);
+      }
+      switch (resource.trim().toLowerCase()) {
+        case CATALOG:
+          catalogName = userInput;
+          break;
+        case SCHEMA:
+          schemaName = userInput;
+        case TABLE:
+          tableName = userInput;
+          break;
+        case COLUMN:
+          columnName = userInput;
+          break;
+        default:
+          break;
+      }
+    }
+
+    if (serviceName != null && userInput != null) {
+      try {
+
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("==> PrestoResourceMgr.getPrestoResources() UserInput: " + userInput + " configs: " + configs + " catalogList: " + catalogList + " tableList: "
+            + tableList + " columnList: " + columnList);
+        }
+
+        final PrestoClient prestoClient = new PrestoConnectionManager().getPrestoConnection(serviceName, serviceType, configs);
+
+        Callable<List<String>> callableObj = null;
+
+        final String finalCatalogName;
+        final String finalSchemaName;
+        final String finalTableName;
+        final String finalColumnName;
+
+        final List<String> finalCatalogList = catalogList;
+        final List<String> finalSchemaList = schemaList;
+        final List<String> finalTableList = tableList;
+        final List<String> finalColumnList = columnList;
+
+        if (prestoClient != null) {
+          if (catalogName != null && !catalogName.isEmpty()) {
+            finalCatalogName = catalogName;
+            callableObj = new Callable<List<String>>() {
+              @Override
+              public List<String> call() throws Exception {
+                return prestoClient.getCatalogList(finalCatalogName, finalCatalogList);
+              }
+            };
+          } else if (schemaName != null && !schemaName.isEmpty()) {
+            finalSchemaName = schemaName;
+            callableObj = new Callable<List<String>>() {
+              @Override
+              public List<String> call() throws Exception {
+                return prestoClient.getSchemaList(finalSchemaName, finalCatalogList, finalSchemaList);
+              }
+            };
+          } else if (tableName != null && !tableName.isEmpty()) {
+            finalTableName = tableName;
+            callableObj = new Callable<List<String>>() {
+              @Override
+              public List<String> call() throws Exception {
+                return prestoClient.getTableList(finalTableName, finalCatalogList, finalSchemaList, finalTableList);
+              }
+            };
+          } else if (columnName != null && !columnName.isEmpty()) {
+            // Column names are matched by the wildcardmatcher
+            columnName += "*";
+            finalColumnName = columnName;
+            callableObj = new Callable<List<String>>() {
+              @Override
+              public List<String> call() throws Exception {
+                return prestoClient.getColumnList(finalColumnName, finalCatalogList, finalSchemaList, finalTableList, finalColumnList);
+              }
+            };
+          }
+          if (callableObj != null) {
+            synchronized (prestoClient) {
+              resultList = TimedEventUtil.timedTask(callableObj, 5, TimeUnit.SECONDS);
+            }
+          } else {
+            LOG.error("Could not initiate a PrestoClient timedTask");
+          }
+        }
+      } catch (Exception e) {
+        LOG.error("Unable to get Presto resource", e);
+        throw e;
+      }
+    }
+    return resultList;
+  }
+}
diff --git a/pom.xml b/pom.xml
index 40b053b..48cde0a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -158,6 +158,7 @@
         <noggit.version>0.8</noggit.version>
         <owasp-java-html-sanitizer.version>r239</owasp-java-html-sanitizer.version>
         <paranamer.version>2.3</paranamer.version>
+        <presto.version>310</presto.version>
         <poi.version>3.17</poi.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <protobuf-java.version>2.5.0</protobuf-java.version>
@@ -184,6 +185,12 @@
 		<kstruct.gethostname4j.version>0.0.2</kstruct.gethostname4j.version>
 		<jna.version>5.2.0</jna.version>
 		<jna-platform.version>5.2.0</jna-platform.version>
+        <!-- presto plugin deps -->
+        <presto.airlift.version>0.178</presto.airlift.version>
+        <presto.bval-jsr.version>2.0.0</presto.bval-jsr.version>
+        <presto.guice.version>4.2.2</presto.guice.version>
+        <presto.guava.version>26.0-jre</presto.guava.version>
+        <presto.validation-api.version>2.0.1.Final</presto.validation-api.version>
     </properties>
     <profiles>
         <profile>
@@ -211,6 +218,7 @@
                 <module>plugin-solr</module>
                 <module>plugin-nifi</module>
                 <module>plugin-nifi-registry</module>
+                <module>plugin-presto</module>
                 <module>ugsync</module>
                 <module>ugsync/ldapconfigchecktool/ldapconfigcheck</module>
                 <module>unixauthclient</module>
@@ -229,6 +237,7 @@
                 <module>ranger-solr-plugin-shim</module>
                 <module>ranger-atlas-plugin-shim</module>
                 <module>ranger-kms-plugin-shim</module>
+                <module>ranger-presto-plugin-shim</module>
                 <module>ranger-examples</module>
                 <module>ranger-tools</module>
                 <module>plugin-atlas</module>
@@ -265,6 +274,7 @@
                                 <descriptor>src/main/assembly/plugin-sqoop.xml</descriptor>
                                 <descriptor>src/main/assembly/plugin-kylin.xml</descriptor>
                                 <descriptor>src/main/assembly/plugin-elasticsearch.xml</descriptor>
+                                <descriptor>src/main/assembly/plugin-presto.xml</descriptor>
                             </descriptors>
                         </configuration>
                     </plugin>
@@ -623,6 +633,33 @@
             </build>
         </profile>
         <profile>
+            <id>ranger-presto-plugin</id>
+            <modules>
+                <module>agents-audit</module>
+                <module>agents-common</module>
+                <module>agents-cred</module>
+                <module>agents-installer</module>
+                <module>credentialbuilder</module>
+                <module>ranger-plugin-classloader</module>
+                <module>ranger-util</module>
+                <module>plugin-presto</module>
+                <module>ranger-presto-plugin-shim</module>
+            </modules>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <version>2.2-beta-5</version>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>src/main/assembly/plugin-presto.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
             <id>linux</id>
             <activation>
                 <os>
@@ -676,6 +713,8 @@
                 <module>ranger-kylin-plugin-shim</module>
                 <module>plugin-elasticsearch</module>
                 <module>ranger-elasticsearch-plugin-shim</module>
+                <module>plugin-presto</module>
+                <module>ranger-presto-plugin-shim</module>
                 <module>unixauthnative</module>
             </modules>
             <build>
@@ -704,6 +743,7 @@
                                 <descriptor>src/main/assembly/plugin-sqoop.xml</descriptor>
                                 <descriptor>src/main/assembly/plugin-kylin.xml</descriptor>
                                 <descriptor>src/main/assembly/plugin-elasticsearch.xml</descriptor>
+                                <descriptor>src/main/assembly/plugin-presto.xml</descriptor>
                             </descriptors>
                         </configuration>
                     </plugin>
diff --git a/ranger-presto-plugin-shim/pom.xml b/ranger-presto-plugin-shim/pom.xml
new file mode 100644
index 0000000..91ca8e8
--- /dev/null
+++ b/ranger-presto-plugin-shim/pom.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>ranger-presto-plugin-shim</artifactId>
+    <name>Presto Security Plugin Shim</name>
+    <description>Presto Security Plugin Shim</description>
+    <packaging>jar</packaging>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <parent>
+        <groupId>org.apache.ranger</groupId>
+        <artifactId>ranger</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.prestosql</groupId>
+            <artifactId>presto-spi</artifactId>
+            <version>${presto.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugin-classloader</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.airlift</groupId>
+            <artifactId>bootstrap</artifactId>
+            <version>${presto.airlift.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.airlift</groupId>
+            <artifactId>log</artifactId>
+            <version>${presto.airlift.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.airlift</groupId>
+            <artifactId>configuration</artifactId>
+            <version>${presto.airlift.version}</version>
+        </dependency>
+
+        <!-- for the assembly -->
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${presto.guava.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <version>${presto.guice.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+            <version>${presto.validation-api.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.bval</groupId>
+            <artifactId>bval-jsr</artifactId>
+            <version>${presto.bval-jsr.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>${httpcomponents.httpcore.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.zookeeper</groupId>
+            <artifactId>zookeeper</artifactId>
+            <version>${zookeeper.version}</version>
+        </dependency>
+
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/PrestoRangerPlugin.java b/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/PrestoRangerPlugin.java
new file mode 100644
index 0000000..fe70772
--- /dev/null
+++ b/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/PrestoRangerPlugin.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ranger.authorization.presto.authorizer;
+
+import io.prestosql.spi.Plugin;
+import io.prestosql.spi.security.SystemAccessControlFactory;
+
+import java.util.ArrayList;
+
+public class PrestoRangerPlugin
+        implements Plugin
+{
+    @Override
+    public Iterable<SystemAccessControlFactory> getSystemAccessControlFactories()
+    {
+        ArrayList<SystemAccessControlFactory> list = new ArrayList<>();
+        SystemAccessControlFactory factory = new RangerSystemAccessControlFactory();
+        list.add(factory);
+        return list;
+    }
+}
diff --git a/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerConfig.java b/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerConfig.java
new file mode 100644
index 0000000..67b0d24
--- /dev/null
+++ b/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerConfig.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.authorization.presto.authorizer;
+
+import io.airlift.configuration.Config;
+import io.airlift.configuration.ConfigDescription;
+
+public class RangerConfig {
+  private String keytab;
+  private String principal;
+
+  public String getKeytab() { return keytab; }
+
+  @Config("ranger.keytab")
+  @ConfigDescription("Keytab for authentication against Ranger")
+  @SuppressWarnings("unused")
+  public RangerConfig setKeytab(String keytab) {
+    this.keytab = keytab;
+    return this;
+  }
+
+  public String getPrincipal() { return principal; }
+
+  @Config("ranger.principal")
+  @ConfigDescription("Principal for authentication against Ranger with keytab")
+  @SuppressWarnings("unused")
+  public RangerConfig setPrincipal(String principal) {
+    this.principal = principal;
+    return this;
+  }
+}
diff --git a/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerSystemAccessControl.java b/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerSystemAccessControl.java
new file mode 100644
index 0000000..e89f646
--- /dev/null
+++ b/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerSystemAccessControl.java
@@ -0,0 +1,382 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ranger.authorization.presto.authorizer;
+
+import io.prestosql.spi.connector.CatalogSchemaName;
+import io.prestosql.spi.connector.CatalogSchemaTableName;
+import io.prestosql.spi.connector.SchemaTableName;
+import io.prestosql.spi.security.AccessDeniedException;
+import io.prestosql.spi.security.Identity;
+import io.prestosql.spi.security.SystemAccessControl;
+import org.apache.ranger.plugin.classloader.RangerPluginClassLoader;
+
+import javax.inject.Inject;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+public class RangerSystemAccessControl
+  implements SystemAccessControl {
+  private static final String RANGER_PLUGIN_TYPE = "presto";
+  private static final String RANGER_PRESTO_AUTHORIZER_IMPL_CLASSNAME = "org.apache.ranger.authorization.presto.authorizer.RangerSystemAccessControl";
+
+  final private RangerPluginClassLoader rangerPluginClassLoader;
+  final private SystemAccessControl systemAccessControlImpl;
+
+  @Inject
+  public RangerSystemAccessControl(RangerConfig config) {
+    try {
+      rangerPluginClassLoader = RangerPluginClassLoader.getInstance(RANGER_PLUGIN_TYPE, this.getClass());
+
+      @SuppressWarnings("unchecked")
+      Class<SystemAccessControl> cls = (Class<SystemAccessControl>) Class.forName(RANGER_PRESTO_AUTHORIZER_IMPL_CLASSNAME, true, rangerPluginClassLoader);
+
+      activatePluginClassLoader();
+
+      Map<String, String> configMap = new HashMap<>();
+      if (config.getKeytab() != null && config.getPrincipal() != null) {
+        configMap.put("ranger.keytab", config.getKeytab());
+        configMap.put("ranger.principal", config.getPrincipal());
+      }
+      systemAccessControlImpl = cls.getDeclaredConstructor(Map.class).newInstance(configMap);
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    } finally {
+      deactivatePluginClassLoader();
+    }
+  }
+
+  @Override
+  public void checkCanSetUser(Optional<Principal> principal, String userName) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanSetUser(principal, userName);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denySetUser(principal, userName);
+    }
+  }
+
+  @Override
+  public void checkCanSetSystemSessionProperty(Identity identity, String propertyName) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanSetSystemSessionProperty(identity, propertyName);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denySetSystemSessionProperty(propertyName);
+    }
+  }
+
+  @Override
+  public void checkCanAccessCatalog(Identity identity, String catalogName) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanAccessCatalog(identity, catalogName);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyCatalogAccess(catalogName);
+    }
+  }
+
+  @Override
+  public Set<String> filterCatalogs(Identity identity, Set<String> catalogs) {
+    return catalogs;
+  }
+
+  @Override
+  public void checkCanCreateSchema(Identity identity, CatalogSchemaName schema) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanCreateSchema(identity, schema);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyCreateSchema(schema.getSchemaName());
+    }
+  }
+
+  @Override
+  public void checkCanDropSchema(Identity identity, CatalogSchemaName schema) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanDropSchema(identity, schema);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyDropSchema(schema.getSchemaName());
+    }
+  }
+
+  @Override
+  public void checkCanRenameSchema(Identity identity, CatalogSchemaName schema, String newSchemaName) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanRenameSchema(identity, schema, newSchemaName);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyRenameSchema(schema.getSchemaName(), newSchemaName);
+    }
+  }
+
+  @Override
+  public void checkCanShowSchemas(Identity identity, String catalogName) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanShowSchemas(identity, catalogName);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyShowSchemas();
+    }
+  }
+
+  @Override
+  public Set<String> filterSchemas(Identity identity, String catalogName, Set<String> schemaNames) {
+    return schemaNames;
+  }
+
+  @Override
+  public void checkCanCreateTable(Identity identity, CatalogSchemaTableName table) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanCreateTable(identity, table);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyCreateTable(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanDropTable(Identity identity, CatalogSchemaTableName table) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanDropTable(identity, table);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyDropTable(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanRenameTable(Identity identity, CatalogSchemaTableName table, CatalogSchemaTableName newTable) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanRenameTable(identity, table, newTable);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyRenameTable(table.getSchemaTableName().getTableName(), newTable.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanShowTablesMetadata(Identity identity, CatalogSchemaName schema) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanShowTablesMetadata(identity, schema);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyShowTablesMetadata(schema.getSchemaName());
+    }
+  }
+
+  @Override
+  public Set<SchemaTableName> filterTables(Identity identity, String catalogName, Set<SchemaTableName> tableNames) {
+    return tableNames;
+  }
+
+  @Override
+  public void checkCanAddColumn(Identity identity, CatalogSchemaTableName table) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanAddColumn(identity, table);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyAddColumn(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanDropColumn(Identity identity, CatalogSchemaTableName table) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanDropColumn(identity, table);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyDropColumn(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanRenameColumn(Identity identity, CatalogSchemaTableName table) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanRenameColumn(identity, table);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyRenameColumn(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanSelectFromColumns(Identity identity, CatalogSchemaTableName table, Set<String> columns) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanSelectFromColumns(identity, table, columns);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denySelectColumns(table.getSchemaTableName().getTableName(), columns);
+    }
+  }
+
+  @Override
+  public void checkCanInsertIntoTable(Identity identity, CatalogSchemaTableName table) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanInsertIntoTable(identity, table);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyInsertTable(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanDeleteFromTable(Identity identity, CatalogSchemaTableName table) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanDeleteFromTable(identity, table);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyDeleteTable(table.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanCreateView(Identity identity, CatalogSchemaTableName view) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanCreateView(identity, view);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyCreateView(view.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanDropView(Identity identity, CatalogSchemaTableName view) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanDropView(identity, view);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyDropView(view.getSchemaTableName().getTableName());
+    }
+  }
+
+  @Override
+  public void checkCanCreateViewWithSelectFromColumns(Identity identity, CatalogSchemaTableName table, Set<String> columns) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanCreateViewWithSelectFromColumns(identity, table, columns);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denyCreateViewWithSelect(table.getSchemaTableName().getTableName(), identity);
+    }
+  }
+
+  @Override
+  public void checkCanSetCatalogSessionProperty(Identity identity, String catalogName, String propertyName) {
+    try {
+      activatePluginClassLoader();
+      systemAccessControlImpl.checkCanSetCatalogSessionProperty(identity, catalogName, propertyName);
+    } catch (AccessDeniedException e) {
+      deactivatePluginClassLoader();
+      throw e;
+    } catch (Exception e) {
+      deactivatePluginClassLoader();
+      AccessDeniedException.denySetCatalogSessionProperty(catalogName, propertyName);
+    }
+  }
+
+  private void activatePluginClassLoader() {
+    if (rangerPluginClassLoader != null) {
+      rangerPluginClassLoader.activate();
+    }
+  }
+
+  private void deactivatePluginClassLoader() {
+    if (rangerPluginClassLoader != null) {
+      rangerPluginClassLoader.deactivate();
+    }
+  }
+}
diff --git a/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerSystemAccessControlFactory.java b/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerSystemAccessControlFactory.java
new file mode 100644
index 0000000..e446ada
--- /dev/null
+++ b/ranger-presto-plugin-shim/src/main/java/org/apache/ranger/authorization/presto/authorizer/RangerSystemAccessControlFactory.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ranger.authorization.presto.authorizer;
+
+import com.google.inject.Injector;
+import com.google.inject.Scopes;
+import io.airlift.bootstrap.Bootstrap;
+import io.prestosql.spi.security.SystemAccessControl;
+import io.prestosql.spi.security.SystemAccessControlFactory;
+
+import java.util.Map;
+
+import static com.google.common.base.Throwables.throwIfUnchecked;
+import static io.airlift.configuration.ConfigBinder.configBinder;
+import static java.util.Objects.requireNonNull;
+
+public class RangerSystemAccessControlFactory
+  implements SystemAccessControlFactory {
+  private static final String NAME = "ranger";
+
+  @Override
+  public String getName() {
+    return NAME;
+  }
+
+  @Override
+  public SystemAccessControl create(Map<String, String> config) {
+    requireNonNull(config, "config is null");
+
+    try {
+      Bootstrap app = new Bootstrap(
+        binder -> {
+          configBinder(binder).bindConfig(RangerConfig.class);
+          binder.bind(RangerSystemAccessControl.class).in(Scopes.SINGLETON);
+        }
+      );
+
+      Injector injector = app
+        .strictConfig()
+        .doNotInitializeLogging()
+        .setRequiredConfigurationProperties(config)
+        .initialize();
+
+      return injector.getInstance(RangerSystemAccessControl.class);
+    } catch (Exception e) {
+      throwIfUnchecked(e);
+      throw new RuntimeException(e);
+    }
+  }
+}
diff --git a/ranger-presto-plugin-shim/src/main/resources/META-INF/services/io.prestosql.spi.Plugin b/ranger-presto-plugin-shim/src/main/resources/META-INF/services/io.prestosql.spi.Plugin
new file mode 100644
index 0000000..ff40776
--- /dev/null
+++ b/ranger-presto-plugin-shim/src/main/resources/META-INF/services/io.prestosql.spi.Plugin
@@ -0,0 +1,15 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+org.apache.ranger.authorization.presto.authorizer.PrestoRangerPlugin
diff --git a/src/main/assembly/admin-web.xml b/src/main/assembly/admin-web.xml
index c862155..670ec1b 100644
--- a/src/main/assembly/admin-web.xml
+++ b/src/main/assembly/admin-web.xml
@@ -403,6 +403,27 @@
               <include>org.apache.ranger:ranger-elasticsearch-plugin</include>
           </includes>
       </moduleSet>
+      <moduleSet>
+          <binaries>
+              <includeDependencies>true</includeDependencies>
+              <outputDirectory>/ews/webapp/WEB-INF/classes/ranger-plugins/presto</outputDirectory>
+              <unpack>false</unpack>
+              <directoryMode>755</directoryMode>
+              <fileMode>644</fileMode>
+              <dependencySets>
+                  <dependencySet>
+                      <includes>
+                          <include>io.prestosql:presto-spi:jar:${presto.version}</include>
+                          <include>io.prestosql:presto-jdbc:jar:${presto.version}</include>
+                      </includes>
+                  </dependencySet>
+              </dependencySets>
+          </binaries>
+          <includes>
+              <include>org.apache.ranger:ranger-presto-plugin</include>
+          </includes>
+      </moduleSet>
+
   </moduleSets>
 
   <fileSets>
diff --git a/src/main/assembly/plugin-presto.xml b/src/main/assembly/plugin-presto.xml
new file mode 100644
index 0000000..8063a9d
--- /dev/null
+++ b/src/main/assembly/plugin-presto.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<assembly>
+    <id>presto-plugin</id>
+    <formats>
+        <format>tar.gz</format>
+        <format>zip</format>
+    </formats>
+    <baseDirectory>${project.name}-${project.version}-presto-plugin</baseDirectory>
+    <includeBaseDirectory>true</includeBaseDirectory>
+    <moduleSets>
+        <moduleSet>
+            <binaries>
+                <includeDependencies>false</includeDependencies>
+                <unpack>false</unpack>
+                <directoryMode>755</directoryMode>
+                <fileMode>644</fileMode>
+                <outputDirectory>/lib</outputDirectory>
+                <dependencySets>
+                    <dependencySet>
+                        <outputDirectory>/lib</outputDirectory>
+                        <unpack>false</unpack>
+                        <includes>
+                            <include>com.google.inject:guice:jar:${presto.guice.version}</include>
+                            <include>com.google.guava:guava:jar:${presto.guava.version}</include>
+                            <include>io.airlift:bootstrap:jar:${presto.airlift.version}</include>
+                            <include>io.airlift:log:jar:${presto.airlift.version}</include>
+                            <include>io.airlift:log-manager:jar:${presto.airlift.version}</include>
+                            <include>io.airlift:configuration:jar:${presto.airlift.version}</include>
+                            <include>javax.validation:validation-api:jar:${presto.validation-api.version}</include>
+                            <include>javax.inject:javax.inject:jar:${javax-inject.version}</include>
+                            <include>org.apache.bval:bval-jsr:jar:${presto.bval-jsr.version}</include>
+                            <include>org.slf4j:slf4j-api:jar:${slf4j-api.version}</include>
+                        </includes>
+                    </dependencySet>
+                </dependencySets>
+            </binaries>
+            <includes>
+                <include>org.apache.ranger:ranger-presto-plugin-shim</include>
+                <include>org.apache.ranger:ranger-plugin-classloader</include>
+            </includes>
+        </moduleSet>
+
+        <moduleSet>
+            <binaries>
+                <includeDependencies>false</includeDependencies>
+                <unpack>false</unpack>
+                <directoryMode>755</directoryMode>
+                <fileMode>644</fileMode>
+                <dependencySets>
+                    <dependencySet>
+                        <outputDirectory>/lib/ranger-presto-plugin-impl</outputDirectory>
+                        <unpack>false</unpack>
+                        <includes>
+                            <include>com.google.code.gson:gson*</include>
+                            <include>org.eclipse.persistence:eclipselink</include>
+                            <include>org.eclipse.persistence:javax.persistence</include>
+                            <include>org.apache.httpcomponents:httpmime:jar:${httpcomponents.httpmime.version}</include>
+                            <include>org.apache.httpcomponents:httpclient:jar:${httpcomponents.httpclient.version}</include>
+                            <include>org.apache.httpcomponents:httpcore:jar:${httpcomponents.httpcore.version}</include>
+                            <include>org.noggit:noggit:jar:${noggit.version}</include>
+                            <include>org.apache.solr:solr-solrj</include>
+                            <include>com.sun.jersey:jersey-core</include>
+                            <include>com.sun.jersey:jersey-server</include>
+                            <include>commons-cli:commons-cli</include>
+                            <include>commons-collections:commons-collections</include>
+                            <include>org.apache.commons:commons-configuration2:jar:${commons.configuration.version}</include>
+                            <include>commons-io:commons-io:jar:${commons.io.version}</include>
+                            <include>commons-lang:commons-lang:jar:${commons.lang.version}</include>
+                            <include>commons-logging:commons-logging:jar:${commons.logging.version}</include>
+                            <include>com.google.guava:guava:jar:${google.guava.version}</include>
+                            <include>org.apache.hadoop:hadoop-common:jar:${hadoop.version}</include>
+                            <include>org.apache.hadoop:hadoop-auth:jar:${hadoop.version}</include>
+                            <include>org.apache.ranger:ranger-plugins-cred</include>
+                            <include>org.apache.ranger:credentialbuilder</include>
+                            <include>org.codehaus.woodstox:stax2-api</include>
+                            <include>com.fasterxml.woodstox:woodstox-core</include>
+                            <include>org.apache.htrace:htrace-core4</include>
+                            <include>com.sun.jersey:jersey-bundle</include>
+                            <include>com.sun.jersey:jersey-json</include>
+                            <include>org.codehaus.jackson:jackson-core-asl</include>
+                            <include>org.codehaus.jackson:jackson-jaxrs</include>
+                            <include>org.codehaus.jackson:jackson-mapper-asl</include>
+                            <include>org.codehaus.jackson:jackson-xc</include>
+                            <include>org.apache.zookeeper:zookeeper:jar:${zookeeper.version}</include>
+                        </includes>
+                    </dependencySet>
+                </dependencySets>
+                <outputDirectory>/lib/ranger-presto-plugin-impl</outputDirectory>
+            </binaries>
+            <includes>
+                <include>org.apache.ranger:ranger-plugins-audit</include>
+                <include>org.apache.ranger:ranger-plugins-cred</include>
+                <include>org.apache.ranger:ranger-plugins-common</include>
+                <include>org.apache.ranger:ranger-presto-plugin</include>
+            </includes>
+        </moduleSet>
+        <moduleSet>
+            <binaries>
+                <includeDependencies>true</includeDependencies>
+                <dependencySets>
+                    <dependencySet>
+                        <outputDirectory>/install/lib</outputDirectory>
+                        <unpack>false</unpack>
+                        <includes>
+                            <include>commons-cli:commons-cli</include>
+                            <include>commons-collections:commons-collections</include>
+                            <include>org.apache.commons:commons-configuration2:jar:${commons.configuration.version}</include>
+                            <include>commons-io:commons-io:jar:${commons.io.version}</include>
+                            <include>commons-lang:commons-lang</include>
+                            <include>commons-logging:commons-logging:jar:${commons.logging.version}</include>
+                            <include>com.google.guava:guava:jar:${google.guava.version}</include>
+                            <include>org.slf4j:slf4j-api:jar:${slf4j-api.version}</include>
+                            <include>org.apache.hadoop:hadoop-common:jar:${hadoop.version}</include>
+                            <include>org.apache.hadoop:hadoop-auth:jar:${hadoop.version}</include>
+                            <include>org.codehaus.woodstox:stax2-api</include>
+                            <include>com.fasterxml.woodstox:woodstox-core</include>
+                            <include>org.apache.htrace:htrace-core4</include>
+                        </includes>
+                    </dependencySet>
+                </dependencySets>
+                <outputDirectory>/install/lib</outputDirectory>
+                <unpack>false</unpack>
+            </binaries>
+            <includes>
+                <include>org.apache.ranger:ranger-plugins-installer</include>
+                <include>org.apache.ranger:credentialbuilder</include>
+            </includes>
+        </moduleSet>
+    </moduleSets>
+    <fileSets>
+        <!-- conf.templates for enable -->
+        <fileSet>
+            <outputDirectory>/install/conf.templates/enable</outputDirectory>
+            <directory>plugin-presto/conf</directory>
+            <excludes>
+                <exclude>*.sh</exclude>
+            </excludes>
+            <fileMode>700</fileMode>
+        </fileSet>
+        <fileSet>
+            <outputDirectory>/install/conf.templates/disable</outputDirectory>
+            <directory>plugin-presto/disable-conf</directory>
+            <fileMode>700</fileMode>
+        </fileSet>
+        <fileSet>
+            <outputDirectory>/install/conf.templates/default</outputDirectory>
+            <directory>plugin-presto/template</directory>
+            <fileMode>700</fileMode>
+        </fileSet>
+        <!-- version file -->
+        <fileSet>
+            <outputDirectory>/</outputDirectory>
+            <directory>${project.build.outputDirectory}</directory>
+            <includes>
+                <include>version</include>
+            </includes>
+            <fileMode>444</fileMode>
+        </fileSet>
+    </fileSets>
+    <!-- enable/disable script for Plugin -->
+    <files>
+        <file>
+            <source>agents-common/scripts/enable-agent.sh</source>
+            <outputDirectory>/</outputDirectory>
+            <destName>enable-presto-plugin.sh</destName>
+            <fileMode>755</fileMode>
+        </file>
+        <file>
+            <source>agents-common/scripts/enable-agent.sh</source>
+            <outputDirectory>/</outputDirectory>
+            <destName>disable-presto-plugin.sh</destName>
+            <fileMode>755</fileMode>
+        </file>
+        <file>
+            <source>plugin-presto/scripts/install.properties</source>
+            <outputDirectory>/</outputDirectory>
+            <destName>install.properties</destName>
+            <fileMode>755</fileMode>
+        </file>
+        <file>
+            <source>security-admin/scripts/ranger_credential_helper.py</source>
+            <outputDirectory>/</outputDirectory>
+            <fileMode>755</fileMode>
+        </file>
+    </files>
+</assembly>