I'm attempting to put a POC together that leverages the SQL Server 2019 Extensibility Framework & External Languages feature. This enables execution of external languages in SQL Server Stored procedures. I've written a JAR file that encrypts and decrypts data being passed via a SQL Server stored procedure. I've confirmed that the each method is correct, and returns the correct values when not being sent as a stored procedure. However, when executing the stored procedure I receive an empty data set and see the following error in debug mode:
java.io.FileNotFoundException: <jks-file-location> (Access is denied)
The line of Java code throwing the error is below:
Key _key = readKeyFromStore_cbs("<jks-file-location>, "<password>".toCharArray(), "entityEncryption", "<password>".toCharArray());
_keySpec = new SecretKeySpec(_key.getEncoded(), _key.getAlgorithm());
Again, the code is fine, I don't think there are issues there, and don't think posting the content of those methods is the issue (the SP itself runs fine with dummy data in the place of data being encrypted and decrypted, and the code with encryption and decryption runs as expected when run on its own).
Additional Info:
I'm running this on a local Windows 10 environment and have given "Everyone" full security permissions on the jks.
I've double checked the user running sql server and ensured that user has full permissions on the file as well. (This user also has admin privileges on SQL Server)
I've checked SQL Server sp_configure options as well.
Filestream is enabled and set to full control in sp_configure
I've even disabled clr strict security on sp_configure to see if that was the cause. I still receive the same error.
I've attempted tests with JKS in my User directory (with permissions on the directory and file for the SQL Server user), in the C drive, and in the child directory of the C drive (again, with permissions on the directory and file for the SQL Server user)
The stored procedure runs, but is returning an empty data set. When attempting run without encryption (using the key from the currently inaccessible keystore) and using dummy data, I receive the expected data set.
Anyone know what might be causing this error?
UPDATE:
Moving the JAR and jks into SQL Server directories and starting the Launchpad service resolved the issue. Hope this helps someone avoid similar frustrations.
Related
It was working from last 3 month but from last 3 days I am facing this issue
Even After creating JNDI in Websphere when I try to connect test connection it giving me the following error.
java.sql.SQLNonTransientException: java.sql.SQLNonTransientException: null DSRA0010E: SQL State = 08001, Error Code = -1,639
I am not able to restart node agent it gives me the following error with ./startNode.sh and ./stopNode.sh
serverNode01/servers/nodeagent/server.xml file is missing
Please give an idea to restart the node agent.
Thanks
The description of SQL1639N:
SQL1639N The database server was unable to perform authentication
because security-related database manager files on the server do not
have the required operating system permissions.
Explanation
The DB2 database system requires that your instance and database
directories, and the files in those directories, have a minimum level
of operating system permissions. When the instance and database
directories are created by the database manager the permissions are
accurate, and changing those permissions could cause database manager
functions to fail. The complexity of DB2 file permissions is increased
in the case of non-root installed instances and operating system-based
authentication.
This message is returned when security-related database manager
executable files do not have necessary permissions for the database
manager to perform remote connection authentication-related tasks.
There are several reasons why these security-related files might not
have the necessary permissions, including the following reasons:
The database manager instance is a non-root installed instance and operating system-based authentication has not been enabled using the
db2rfe command
Operating system permissions of database manager files were accidentally changed
User response
Respond to this message in one of the following ways:
If the instance is a non-root installed instance, enable operating system-based authentication using the db2rfe command.
Reset all of the operating system permissions for the database manager binary files for this instance by running the following
command as a superuser:
db2iupdt -k <instance-name>
where is the name of the affected instance.
Note that both the db2rfe command and the db2iupdt command require
that the database manager instance be stopped and restarted.
Are you able to connect to the database manually from some remote client (using JDBC/ODBC/CLI/DB2 CLP)?
I have a server where I work with a database and files using a java app.
When I start my app I give a report regarding file access to the server using:
public static boolean folderExists(String folderPath) {
File folderToCheck = new File(folderPath);
return folderToCheck.exists();
}
Every time I start my app (after a fresh restart of my computer)
I get a false response, even though the server is on.
The reason is because I must give an authentication as another user.
What I do is access the server through Windows
where I am being asked for username/password,
and after that I get a true response regarding file access to the server.
Is there a way to give the authentication username/password through Java,
and not through Windows?
Thank you
On Windows 'native' Java IO (e.g. java.io.File) always inherits the security context of the user running the JVM process. For example, you could run the Java app as a Windows service with the correct credentials.
The JCIFS project implements CIFS (the Windows SMB file server protocol) and allows you to directly specify the username/password.
See the API for examples.
I am pretty sure, that there is no way to grant fileaccess by java, without a Windows-Call.
You can call cacls file.log /e /t /p Everyone:f but this will be language-dependent.
I had a similar problem: How to change the file ACL in windows, if I only know the SID?
With Java7 there may be a way to do this.
Troubleshooting someone elses problem over the phone.
The error is trying to connect from one server to another servers db over ssl.
The error message is: 'requires a valid client certificate'
I've done everything to ensure that they have created the correct cert.
I had them debug=yes ssl:handshake and send me the logs.
In their logs they have nothing set for the keystore and the wrong path for the truststore.
Herein I think lies the issue. We have an executable jar that reads the paths and passwords for the keystore/truststore and sets the values via calls such as System.setProperty("javax.net.ssl.keyStore", config.getKeyStore());
from within the executable. I've verified at least locally that I can communicate over SSL from 1 server to anothers database in our test environment and all is fine. If I were to remove all of the settings then the error log generated by the ssl:handshake gives me the 'requires a valid client certificate'.
I'm told that the destination server with the DB has its pg_hba file
set properly to accept the communication over SSL from the specified
id.
I've verified that the cert is valid from the CA.
The only thing that I can think of is that the executable jar is not setting the values to the System via the code System.setProperty("javax.net.ssl.keyStore");
Is this a configuration that needs to occur to the Red Hat server to allow the jar to set system properties or is this at the file permission level or ? ? ?
I'm at a loss here and would appreciate any guidance on this issue.
Very difficult environment. I'm on the North-East tasked to assist someone in Midwest to trouble shoot them trying to connect to our Database in the South-West. I have no access to the actual servers and have to try and debug over the phone.
If I start the HSQLDB in server mode using my Java code, the server starts without any problem. However, when I try to connect to the same either through the Java code or through the HSQLDB DatabaseManagerSwing; I am unable to connect.
I started the server with user=conn1 and password=conn1 in memory-only mode. But when connecting to the server it gave me following exception:
java.sql.SQLInvalidAuthorizationSpecException: invalid authorization specification - not found: conn1
I can only connect by giving user=SA and blank password. I am using HSQLDB 2.2.5 and JRE1.7 on Windows7 machine.
Can someone tell me where am I doing wrong?
If you try these server properties with recent versions of HyperSQL, you will probably get an error message as your server properties are not correct. The properties "server.username" and "server.password" are not valid. And the dbname.0 property must be in lowercase.
If you want to create a server database with a user name other than SA, you can append the user and password to the database path:
server.database.0 = file:E:/DB/myDB;user=testuser;password=testpw
server.dbname.0 = mydb
After the server is shutdown, there is no need to include the user and password. The credentials are used only to create the database. After that, the credentials are checked when a connection is made to the server.
2020 update with additional information due to recent questions in comments:
The user name and password specified for database.0 are taken into account only when a new database is created by starting the server. If the database files exist before starting the server, user name and password are unnecessary and are simply ignored.
Other settings for a new database, such as hsqldb.tx=mvcc, can be appended to the database.0 string.
You must have properties for database.0 for your server. You can add properties for database.1 if your server is serving two different databases.
The file path specified for database.0 is hidden from the users that connect to the server. Only the dbname.0 value is used for access, for example:
DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/mydb;uer=testuser;password=testpw")
In the getConnection call, it is better to state the user and password separately to keep the code clear:DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/mydb", "testuser", "testpw")
See the Guide http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html for all the details.
Appears the problem you were running into (at least initially) is that, for HSQL in memory databases, if it's the "first" in memory database (i.e. process just started), the username "has to be" sa (username "sa" is not case sensitive, or it can be empty username, which implies the "default" which is also sa). You can use a blank password, or specify a password. Based on some trial and error, if you want to reconnect to the same (in memory) DB later, you'll have to re-use the same password (blank or otherwise). If you want to use a user other than SA you'd probably have to first connect to your database using SA and execute some "create user" type commands to create new users. Then reconnect using that user (assuming your DB is all in memory).
You can use multiple different in-memory databases (if that's what you're trying to accomplish by specifying a different user) like this:
// change the MySpecialTestDb String for multiple different in memory databases
// or reuse the same value
// to reconnect to a previously created in memory database [i.e. within the same process previously].
String DB_CONNECTION_STR = "jdbc:hsqldb:mem:MySpecialTestDb";
String DB_USERNAME_STR = "sa";
String DB_USERNAME_PASSWORD = "";
DriverManager.getConnection(DB_CONNECTION_STR, DB_USERNAME_STR, DB_USERNAME_PASSWORD);
Each new database you create follows the same system (it must be initial user SA and "adopts" whatever first password you give).
ref: http://www.hsqldb.org/doc/1.8/guide/guide.html#advanced-chapter
Or if you want to just "reset" an in memory database, like between each unit test, see here.
Note that documentation also says "...This feature [default user SA] has a side effect that can confuse new users. If a mistake is made in specifying the path for connecting to an existing database, a connection is nevertheless established to a new database. For troubleshooting purposes, you can specify a connection property ifexists=true ..."
Point no 1) Whenever you create a DB, you have to specify the username and password. You can keep it both blank; But same username and password has to be used while connecting to server.
If you observe script file of your DB, you can see commands like :-
CREATE USER "usr" PASSWORD DIGEST '9003d1df22eb4d3820015070385194c8'
ALTER USER "usr" SET LOCAL TRUE
GRANT DBA TO "usr"
I had created DB with user name "usr" so it appeared in script file in those commands. Now while starting server I do not need to specify user name or password. It will IGNORE this information.
While connecting server you have to give exactly same username and password, you gave while creating DB.
Point no 2)
Make sure that there is no space in path of your DB files. If there is space then enclose the whole path in double quotes.
I struggled a lot to find out this silly mistake of mine.
Now if I start the server wil below command it starts correctly
1) Go to lib of HSQL
cd C:\Users\owner\Documents\Java Project\hsqldb-2.2.9\hsqldb\lib
Then give command
java -cp hsqldb.jar org.hsqldb.Server -database.0 file:"C:\Users\owner\Documents\Java Project\hsqldb-2.2.9\TmpDBLocation\myKauDB" -dbname.0 xdb
2) In other command prompt went to lib location
cd C:\Users\owner\Documents\Java Project\hsqldb-2.2.9\hsqldb\lib
Then connected the Swing UI of HSQL DB by giving command in other command prompt window
java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing --driver org.hsqldb.jdbcDriver --URL jdbc:hsqldb:hsql://localhost/xdb --user "usr" --password ""
In my brand new 2.3.2 installation, after clicking bin/runServer.bat, I managed to connect (with Squirrel) using:
URL: jdbc:hsqldb:hsql://localhost:9001
User: SA
Password: <blank>
I have a server where I work with a database and files using a java app.
When I start my app I give a report regarding file access to the server using:
public static boolean folderExists(String folderPath) {
File folderToCheck = new File(folderPath);
return folderToCheck.exists();
}
Every time I start my app (after a fresh restart of my computer)
I get a false response, even though the server is on.
The reason is because I must give an authentication as another user.
What I do is access the server through Windows
where I am being asked for username/password,
and after that I get a true response regarding file access to the server.
Is there a way to give the authentication username/password through Java,
and not through Windows?
Thank you
On Windows 'native' Java IO (e.g. java.io.File) always inherits the security context of the user running the JVM process. For example, you could run the Java app as a Windows service with the correct credentials.
The JCIFS project implements CIFS (the Windows SMB file server protocol) and allows you to directly specify the username/password.
See the API for examples.
I am pretty sure, that there is no way to grant fileaccess by java, without a Windows-Call.
You can call cacls file.log /e /t /p Everyone:f but this will be language-dependent.
I had a similar problem: How to change the file ACL in windows, if I only know the SID?
With Java7 there may be a way to do this.