| /* |
| * 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.sentry.binding.hive.conf; |
| |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.hive.conf.HiveConf; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| |
| public class HiveAuthzConf extends Configuration { |
| |
| /** |
| * Configuration key used in hive-site.xml to point at sentry-site.xml |
| */ |
| public static final String HIVE_ACCESS_CONF_URL = "hive.access.conf.url"; |
| public static final String HIVE_SENTRY_CONF_URL = "hive.sentry.conf.url"; |
| public static final String HIVE_ACCESS_SUBJECT_NAME = "hive.access.subject.name"; |
| public static final String HIVE_SENTRY_SUBJECT_NAME = "hive.sentry.subject.name"; |
| public static final String HIVE_SENTRY_AUTH_ERRORS = "sentry.hive.authorization.errors"; |
| public static final String HIVE_SENTRY_MOCK_COMPILATION = "sentry.hive.mock.compilation"; |
| public static final String HIVE_SENTRY_MOCK_ERROR = "sentry.hive.mock.error"; |
| public static final String HIVE_SENTRY_PRIVILEGE_ERROR_MESSAGE = "No valid privileges"; |
| /** |
| * Property used to persist the role set in the session. This is not public for now. |
| */ |
| public static final String SENTRY_ACTIVE_ROLE_SET = "hive.sentry.active.role.set"; |
| |
| public static final String HIVE_SENTRY_SECURITY_COMMAND_WHITELIST = |
| "hive.sentry.security.command.whitelist"; |
| public static final String HIVE_SENTRY_SECURITY_COMMAND_WHITELIST_DEFAULT = |
| "set,reset,reload"; |
| |
| public static final String HIVE_SENTRY_SERDE_WHITELIST = "hive.sentry.serde.whitelist"; |
| public static final String HIVE_SENTRY_SERDE_WHITELIST_DEFAULT = "org.apache.hadoop.hive.serde2"; |
| |
| // Disable the serde Uri privileges by default for backward compatibilities. |
| public static final String HIVE_SENTRY_SERDE_URI_PRIVILIEGES_ENABLED = "hive.sentry.turn.on.serde.uri.privileges"; |
| public static final boolean HIVE_SENTRY_SERDE_URI_PRIVILIEGES_ENABLED_DEFAULT = false; |
| |
| public static final String HIVE_UDF_WHITE_LIST = |
| "concat,substr,substring,space,repeat,ascii,lpad,rpad,size,round,floor,sqrt,ceil," + |
| "ceiling,rand,abs,pmod,ln,log2,sin,asin,cos,acos,log10,log,exp,power,pow,sign,pi," + |
| "degrees,radians,atan,tan,e,conv,bin,hex,unhex,base64,unbase64,encode,decode,upper," + |
| "lower,ucase,lcase,trim,ltrim,rtrim,length,reverse,field,find_in_set,initcap,like," + |
| "rlike,regexp,regexp_replace,regexp_extract,parse_url,nvl,split,str_to_map,translate" + |
| ",positive,negative,day,dayofmonth,month,year,hour,minute,second,from_unixtime," + |
| "to_date,weekofyear,last_day,date_add,date_sub,datediff,add_months,get_json_object," + |
| "xpath_string,xpath_boolean,xpath_number,xpath_double,xpath_float,xpath_long," + |
| "xpath_int,xpath_short,xpath,+,-,*,/,%,div,&,|,^,~,current_database,isnull," + |
| "isnotnull,if,in,and,or,=,==,<=>,!=,<>,<,<=,>,>=,not,!,between,ewah_bitmap_and," + |
| "ewah_bitmap_or,ewah_bitmap_empty,boolean,tinyint,smallint,int,bigint,float,double," + |
| "string,date,timestamp,binary,decimal,varchar,char,max,min,sum,count,avg,std,stddev," + |
| "stddev_pop,stddev_samp,variance,var_pop,var_samp,covar_pop,covar_samp,corr," + |
| "histogram_numeric,percentile_approx,collect_set,collect_list,ngrams," + |
| "context_ngrams,ewah_bitmap,compute_stats,percentile," + |
| "array,assert_true,map,struct,named_struct,create_union,case,when,hash,coalesce," + |
| "index,instr,locate,elt,concat_ws,sort_array," + |
| "array_contains,sentences,map_keys,map_values,format_number,printf,greatest,least," + |
| "from_utc_timestamp,to_utc_timestamp,unix_timestamp,to_unix_timestamp,explode," + |
| "inline,json_tuple,parse_url_tuple,posexplode,stack,lead,lag,row_number,rank," + |
| "dense_rank,percent_rank,cume_dist,ntile,first_value,last_value,noop,noopwithmap," + |
| "noopstreaming,noopwithmapstreaming,windowingtablefunction,matchpath"; |
| |
| public static final String HIVE_UDF_BLACK_LIST = "reflect,reflect2,java_method,in_file"; |
| public static final String SENTRY_HIVE_SERVER_DEFAULT = ""; |
| |
| /** |
| * Config setting definitions |
| */ |
| public enum AuthzConfVars { |
| AUTHZ_PROVIDER("sentry.hive.provider", |
| "org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider"), |
| AUTHZ_PROVIDER_RESOURCE("sentry.hive.provider.resource", ""), |
| AUTHZ_PROVIDER_BACKEND("sentry.hive.provider.backend", "org.apache.sentry.provider.file.SimpleFileProviderBackend"), |
| AUTHZ_POLICY_ENGINE("sentry.hive.policy.engine", "org.apache.sentry.policy.engine.common.CommonPolicyEngine"), |
| AUTHZ_PRIVILEGE_CACHE("sentry.hive.privilege.cache", "org.apache.sentry.provider.cache.TreePrivilegeCache"), |
| AUTHZ_POLICY_FILE_FORMATTER( |
| "sentry.hive.policy.file.formatter", |
| "org.apache.sentry.binding.hive.SentryIniPolicyFileFormatter"), |
| AUTHZ_SERVER_NAME("sentry.hive.server", SENTRY_HIVE_SERVER_DEFAULT), |
| AUTHZ_RESTRICT_DEFAULT_DB("sentry.hive.restrict.defaultDB", "false"), |
| SHOWDATABASES_ON_SELECT_ONLY("sentry.showdatabases.select.only", "false"), |
| SHOWTABLES_ON_SELECT_ONLY("sentry.showtables.select.only", "false"), |
| SENTRY_TESTING_MODE("sentry.hive.testing.mode", "false"), |
| AUTHZ_ALLOW_HIVE_IMPERSONATION("sentry.hive.allow.hive.impersonation", "false"), |
| AUTHZ_ONFAILURE_HOOKS("sentry.hive.failure.hooks", ""), |
| AUTHZ_METASTORE_SERVICE_USERS("sentry.metastore.service.users", null), |
| AUTHZ_SYNC_ALTER_WITH_POLICY_STORE("sentry.hive.sync.alter", "true"), |
| AUTHZ_SYNC_CREATE_WITH_POLICY_STORE("sentry.hive.sync.create", "false"), |
| AUTHZ_SYNC_DROP_WITH_POLICY_STORE("sentry.hive.sync.drop", "true"), |
| // Specify authorizing on reading metadata is enabled or not at HMS server |
| AUTHZ_METASTORE_READ_AUTHORIZATION_ENABLED("senry.metastore.read.authorization.enabled", "false"), |
| |
| AUTHZ_PROVIDER_DEPRECATED("hive.sentry.provider", |
| "org.apache.sentry.provider.file.ResourceAuthorizationProvider"), |
| AUTHZ_PROVIDER_DEPRECATED2("sentry.provider", |
| "org.apache.sentry.provider.common.HadoopGroupResourceAuthorizationProvider"), |
| AUTHZ_PROVIDER_RESOURCE_DEPRECATED("hive.sentry.provider.resource", ""), |
| AUTHZ_SERVER_NAME_DEPRECATED("hive.sentry.server", SENTRY_HIVE_SERVER_DEFAULT), |
| AUTHZ_RESTRICT_DEFAULT_DB_DEPRECATED("hive.sentry.restrict.defaultDB", "false"), |
| SENTRY_TESTING_MODE_DEPRECATED("hive.sentry.testing.mode", "false"), |
| AUTHZ_ALLOW_HIVE_IMPERSONATION_DEPRECATED("hive.sentry.allow.hive.impersonation", "false"), |
| AUTHZ_ONFAILURE_HOOKS_DEPRECATED("hive.sentry.failure.hooks", ""); |
| |
| private final String varName; |
| private final String defaultVal; |
| |
| AuthzConfVars(String varName, String defaultVal) { |
| this.varName = varName; |
| this.defaultVal = defaultVal; |
| } |
| |
| public String getVar() { |
| return varName; |
| } |
| |
| public String getDefault() { |
| return defaultVal; |
| } |
| |
| public static String getDefault(String varName) { |
| for (AuthzConfVars oneVar : AuthzConfVars.values()) { |
| if(oneVar.getVar().equalsIgnoreCase(varName)) { |
| return oneVar.getDefault(); |
| } |
| } |
| return null; |
| } |
| } |
| |
| // map of current property names - > deprecated property names. |
| // The binding layer code should work if the deprecated property names are provided, |
| // as long as the new property names aren't also provided. Since the binding code |
| // only calls the new property names, we require a map from current names to deprecated |
| // names in order to check if the deprecated name of a property was set. |
| private static final Map<String, List<AuthzConfVars>> currentToDeprecatedProps = new HashMap<>(); |
| static { |
| currentToDeprecatedProps.put(AuthzConfVars.AUTHZ_PROVIDER.getVar(), |
| Arrays.asList(AuthzConfVars.AUTHZ_PROVIDER_DEPRECATED, AuthzConfVars.AUTHZ_PROVIDER_DEPRECATED2)); |
| currentToDeprecatedProps.put(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE.getVar(), |
| Collections.singletonList(AuthzConfVars.AUTHZ_PROVIDER_RESOURCE_DEPRECATED)); |
| currentToDeprecatedProps.put(AuthzConfVars.AUTHZ_SERVER_NAME.getVar(), |
| Collections.singletonList(AuthzConfVars.AUTHZ_SERVER_NAME_DEPRECATED)); |
| currentToDeprecatedProps.put(AuthzConfVars.AUTHZ_RESTRICT_DEFAULT_DB.getVar(), |
| Collections.singletonList(AuthzConfVars.AUTHZ_RESTRICT_DEFAULT_DB_DEPRECATED)); |
| currentToDeprecatedProps.put(AuthzConfVars.SENTRY_TESTING_MODE.getVar(), |
| Collections.singletonList(AuthzConfVars.SENTRY_TESTING_MODE_DEPRECATED)); |
| currentToDeprecatedProps.put(AuthzConfVars.AUTHZ_ALLOW_HIVE_IMPERSONATION.getVar(), |
| Collections.singletonList(AuthzConfVars.AUTHZ_ALLOW_HIVE_IMPERSONATION_DEPRECATED)); |
| currentToDeprecatedProps.put(AuthzConfVars.AUTHZ_ONFAILURE_HOOKS.getVar(), |
| Collections.singletonList(AuthzConfVars.AUTHZ_ONFAILURE_HOOKS_DEPRECATED)); |
| }; |
| |
| private static final Logger LOG = LoggerFactory |
| .getLogger(HiveAuthzConf.class); |
| public static final String AUTHZ_SITE_FILE = "sentry-site.xml"; |
| private final String hiveAuthzSiteFile; |
| |
| public HiveAuthzConf(URL hiveAuthzSiteURL) { |
| super(); |
| LOG.info("DefaultFS: " + super.get("fs.defaultFS")); |
| addResource(hiveAuthzSiteURL, true); |
| applySystemProperties(); |
| this.hiveAuthzSiteFile = hiveAuthzSiteURL.toString(); |
| } |
| |
| public HiveAuthzConf() { |
| super(); |
| applySystemProperties(); |
| this.hiveAuthzSiteFile = null; |
| } |
| |
| /** |
| * Apply system properties to this object if the property name is defined in ConfVars |
| * and the value is non-null and not an empty string. |
| */ |
| private void applySystemProperties() { |
| Map<String, String> systemProperties = getConfSystemProperties(); |
| for (Entry<String, String> systemProperty : systemProperties.entrySet()) { |
| this.set(systemProperty.getKey(), systemProperty.getValue()); |
| } |
| } |
| |
| /** |
| * This method returns a mapping from config variable name to its value for all config variables |
| * which have been set using System properties |
| */ |
| public static Map<String, String> getConfSystemProperties() { |
| Map<String, String> systemProperties = new HashMap<String, String>(); |
| |
| for (AuthzConfVars oneVar : AuthzConfVars.values()) { |
| String value = System.getProperty(oneVar.getVar()); |
| if (value != null && value.length() > 0) { |
| systemProperties.put(oneVar.getVar(), value); |
| } |
| } |
| return systemProperties; |
| } |
| |
| @Override |
| public String get(String varName) { |
| return get(varName, null); |
| } |
| |
| @Override |
| public String get(String varName, String defaultVal) { |
| String retVal = super.get(varName); |
| if (retVal == null) { |
| // check if the deprecated value is set here |
| String deprecatedPropName = null; |
| if (currentToDeprecatedProps.containsKey(varName)) { |
| for (AuthzConfVars var : currentToDeprecatedProps.get(varName)) { |
| retVal = super.get(var.getVar()); |
| if (retVal != null) { |
| deprecatedPropName = var.getVar(); |
| break; |
| } |
| } |
| } |
| if (retVal == null) { |
| retVal = AuthzConfVars.getDefault(varName); |
| } else { |
| LOG.warn("Using the deprecated config setting " + deprecatedPropName + " instead of " + varName); |
| } |
| } |
| if (retVal == null) { |
| retVal = defaultVal; |
| } |
| return retVal; |
| } |
| |
| public String getHiveAuthzSiteFile() { |
| return hiveAuthzSiteFile; |
| } |
| |
| /** |
| * Extract the authz config file path from given hive conf and load the authz config |
| * @param hiveConf |
| * @return |
| * @throws IllegalArgumentException |
| */ |
| public static HiveAuthzConf getAuthzConf(HiveConf hiveConf) |
| throws IllegalArgumentException { |
| boolean depreicatedConfigFile = false; |
| |
| String hiveAuthzConf = hiveConf.get(HiveAuthzConf.HIVE_SENTRY_CONF_URL); |
| if (hiveAuthzConf == null |
| || (hiveAuthzConf = hiveAuthzConf.trim()).isEmpty()) { |
| hiveAuthzConf = hiveConf.get(HiveAuthzConf.HIVE_ACCESS_CONF_URL); |
| depreicatedConfigFile = true; |
| } |
| |
| if (hiveAuthzConf == null |
| || (hiveAuthzConf = hiveAuthzConf.trim()).isEmpty()) { |
| throw new IllegalArgumentException("Configuration key " |
| + HiveAuthzConf.HIVE_SENTRY_CONF_URL + " value '" + hiveAuthzConf |
| + "' is invalid."); |
| } |
| |
| try { |
| return new HiveAuthzConf(new URL(hiveAuthzConf)); |
| } catch (MalformedURLException e) { |
| if (depreicatedConfigFile) { |
| throw new IllegalArgumentException("Configuration key " |
| + HiveAuthzConf.HIVE_ACCESS_CONF_URL |
| + " specifies a malformed URL '" + hiveAuthzConf + "'", e); |
| } else { |
| throw new IllegalArgumentException("Configuration key " |
| + HiveAuthzConf.HIVE_SENTRY_CONF_URL |
| + " specifies a malformed URL '" + hiveAuthzConf + "'", e); |
| } |
| } |
| } |
| } |