/*
 * 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.
 */

// Policy file for solr. Please keep minimal and avoid wildcards.

// permissions needed for tests to pass, based on properties set by the build system
// NOTE: if the property is not set, the permission entry is ignored.
grant {
  // contain read access to only what we need:
  // 3rd party jar resources (where symlinks are not supported), test-files/ resources
  permission java.io.FilePermission "${common.dir}${/}-", "read";
  permission java.io.FilePermission "${common.dir}${/}..${/}solr${/}-", "read";
  // 3rd party jar resources (where symlinks are supported)
  permission java.io.FilePermission "${user.home}${/}.ivy2${/}cache${/}-", "read";
  // system jar resources
  permission java.io.FilePermission "${java.home}${/}-", "read";
  permission java.io.FilePermission "${junit4.childvm.cwd}", "read";
  permission java.io.FilePermission "${junit4.childvm.cwd}${/}temp", "read,write,delete";
  permission java.io.FilePermission "${junit4.childvm.cwd}${/}temp${/}-", "read,write,delete";
  permission java.io.FilePermission "${junit4.childvm.cwd}${/}jacoco.db", "write";
  permission java.io.FilePermission "${junit4.tempDir}${/}*", "read,write,delete";
  permission java.io.FilePermission "${clover.db.dir}${/}-", "read,write,delete";
  permission java.io.FilePermission "${tests.linedocsfile}", "read";
  // DirectoryFactoryTest messes with these (wtf?)
  permission java.io.FilePermission "/tmp/inst1/conf/solrcore.properties", "read";
  permission java.io.FilePermission "/path/to/myinst/conf/solrcore.properties", "read";
  // TestConfigSets messes with these (wtf?)
  permission java.io.FilePermission "/path/to/solr/home/lib", "read";

  permission java.nio.file.LinkPermission "hard";
  
  // all possibilities of accepting/binding/connections on localhost with ports >=1024:
  permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect,resolve";
  permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
  permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
  // "dead hosts", we try to keep it fast
  permission java.net.SocketPermission "[::1]:4", "connect,resolve";
  permission java.net.SocketPermission "[::1]:6", "connect,resolve";
  permission java.net.SocketPermission "[::1]:8", "connect,resolve";
  
  // Basic permissions needed for Lucene to work:
  permission java.util.PropertyPermission "*", "read,write";

  // needed by gson serialization of junit4 runner: TODO clean that up
  permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
  permission java.lang.RuntimePermission "accessDeclaredMembers";
  // needed by junit4 runner to capture sysout/syserr:
  permission java.lang.RuntimePermission "setIO";
  // needed by randomized runner to catch failures from other threads:
  permission java.lang.RuntimePermission "setDefaultUncaughtExceptionHandler";
  // needed by randomized runner getTopThreadGroup:
  permission java.lang.RuntimePermission "modifyThreadGroup";
  // needed by tests e.g. shutting down executors:
  permission java.lang.RuntimePermission "modifyThread";
  // needed for tons of test hacks etc
  permission java.lang.RuntimePermission "getStackTrace";
  // needed for mock filesystems in tests
  permission java.lang.RuntimePermission "fileSystemProvider";
  // needed for test of IOUtils.spins (maybe it can be avoided)
  permission java.lang.RuntimePermission "getFileStoreAttributes";
  // analyzers/uima: needed by lucene expressions' JavascriptCompiler
  permission java.lang.RuntimePermission "createClassLoader";
  // needed to test unmap hack on platforms that support it
  permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
  // needed by jacoco to dump coverage
  permission java.lang.RuntimePermission "shutdownHooks";
  // needed by org.apache.logging.log4j
  permission java.lang.RuntimePermission "getenv.*";
  permission java.lang.RuntimePermission "getClassLoader";
  permission java.lang.RuntimePermission "setContextClassLoader";
  permission java.lang.RuntimePermission "getStackWalkerWithClassReference";
  // needed by bytebuddy
  permission java.lang.RuntimePermission "defineClass";
  // needed by mockito
  permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
  permission java.lang.RuntimePermission "reflectionFactoryAccess";
  // needed by SolrResourceLoader
  permission java.lang.RuntimePermission "closeClassLoader";
  // needed by HttpSolrClient
  permission java.lang.RuntimePermission "getFileSystemAttributes";
  // needed by hadoop auth (TODO: there is a cleaner way to handle this)
  permission java.lang.RuntimePermission "loadLibrary.jaas";
  permission java.lang.RuntimePermission "loadLibrary.jaas_unix";
  permission java.lang.RuntimePermission "loadLibrary.jaas_nt";
  // needed by hadoop common RawLocalFileSystem for java nio getOwner
  permission java.lang.RuntimePermission "accessUserInformation";
  // needed by hadoop hdfs
  permission java.lang.RuntimePermission "readFileDescriptor";
  permission java.lang.RuntimePermission "writeFileDescriptor";
  // needed by hadoop http
  permission java.lang.RuntimePermission "getProtectionDomain";
  // needed by aws s3 sdk (Apache HTTP Client)
  permission java.lang.RuntimePermission "setFactory";
  permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.reflect";

  // These two *have* to be spelled out a separate
  permission java.lang.management.ManagementPermission "control";
  permission java.lang.management.ManagementPermission "monitor";

  // needed by hadoop htrace
  permission java.net.NetPermission "getNetworkInformation";

  // needed by DIH
  permission java.sql.SQLPermission "deregisterDriver";

  permission java.util.logging.LoggingPermission "control";

  // needed by solr mbeans feature/tests
  // TODO: can we remove wildcard for class names/members?
  permission javax.management.MBeanPermission "*", "getAttribute";
  permission javax.management.MBeanPermission "*", "getMBeanInfo";
  permission javax.management.MBeanPermission "*", "queryMBeans";
  permission javax.management.MBeanPermission "*", "queryNames";
  permission javax.management.MBeanPermission "*", "registerMBean";
  permission javax.management.MBeanPermission "*", "unregisterMBean";
  permission javax.management.MBeanServerPermission "createMBeanServer";
  permission javax.management.MBeanServerPermission "findMBeanServer";
  permission javax.management.MBeanServerPermission "releaseMBeanServer";
  permission javax.management.MBeanTrustPermission "register";

  // needed by hadoop auth
  permission javax.security.auth.AuthPermission "getSubject";
  permission javax.security.auth.AuthPermission "modifyPrincipals";
  permission javax.security.auth.AuthPermission "doAs";
  permission javax.security.auth.AuthPermission "getLoginConfiguration";
  permission javax.security.auth.AuthPermission "setLoginConfiguration";
  permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
  permission javax.security.auth.AuthPermission "modifyPublicCredentials";
  permission javax.security.auth.PrivateCredentialPermission "org.apache.hadoop.security.Credentials * \"*\"", "read";

  // needed by hadoop security
  permission java.security.SecurityPermission "putProviderProperty.SaslPlainServer";
  permission java.security.SecurityPermission "insertProvider";

  permission javax.xml.bind.JAXBPermission "setDatatypeConverter";

  // SSL related properties for Solr tests
  permission javax.net.ssl.SSLPermission "setDefaultSSLContext";

  // SASL/Kerberos related properties for Solr tests
  permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KerberosTicket * \"*\"", "read";
  
  // may only be necessary with Java 7?
  permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KeyTab * \"*\"", "read";
  permission javax.security.auth.PrivateCredentialPermission "sun.security.jgss.krb5.Krb5Util$KeysFromKeyTab * \"*\"", "read";
  
  permission javax.security.auth.kerberos.ServicePermission "*", "initiate";
  permission javax.security.auth.kerberos.ServicePermission "*", "accept";
  permission javax.security.auth.kerberos.DelegationPermission "\"*\" \"krbtgt/EXAMPLE.COM@EXAMPLE.COM\"";
  
  // java 8 accessibility requires this perm - should not after 8 I believe (rrd4j is the root reason we hit an accessibility code path)
  permission java.awt.AWTPermission "*";

  // used by solr to create sandboxes (e.g. script execution)
  permission java.security.SecurityPermission "createAccessControlContext";
};

// additional permissions based on system properties set by /bin/solr
// NOTE: if the property is not set, the permission entry is ignored.
grant {
  permission java.io.FilePermission "${hadoop.security.credential.provider.path}", "read,write,delete,readlink";
  permission java.io.FilePermission "${hadoop.security.credential.provider.path}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.jetty.keystore}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.jetty.keystore}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.jetty.truststore}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.jetty.truststore}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.install.dir}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.install.dir}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${jetty.home}", "read,write,delete,readlink";
  permission java.io.FilePermission "${jetty.home}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.solr.home}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.solr.home}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.data.home}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.data.home}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.default.confdir}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.default.confdir}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.log.dir}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.log.dir}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${log4j.configurationFile}", "read,write,delete,readlink";

  // Credentials for S3 Repository
  permission java.io.FilePermission "${aws.sharedCredentialsFile}", "read,readlink";
  permission java.io.FilePermission "${aws.configFile}", "read,readlink";
  permission java.io.FilePermission "${user.home}${/}.aws${/}-", "read,readlink";

  // expanded to a wildcard if set, allows all networking everywhere
  permission java.net.SocketPermission "${solr.internal.network.permission}", "accept,listen,connect,resolve";
};
