DB2 JDBC Windows Authentication - jdbc

Looking for example using JDBC on DB2 database using Windows authentication, preferably with db2jcc4.jar driver. Seems like a common enough scenario, but I'm having a hard time finding an example.

Your original question was too vague until you clarified it with a comment asking how to connect to local Db2-databases via jdbc without a userid/password. So your real question appears to be "how do I achieve passwordless authentication to local Db2-databases on MS-Windows?", which may be a FAQ.
Db2-server delegates authentication to the underlying operating-system services on which the Db2-server is running. Keep in mind that Db2-server runs on a few quite-distinct operating systems, only one of which is MS-Windows.
Yes you can connect via-JDBC to a local Db2-database on MS-Windows without specifying a userid/password, using the IBM-supplied jdbc driver.
You can also connect to a local Db2-database on MS-Windows via CLI/ODBC and command-line without specifying a userid/password. When no userid/password is specified then the authentication-ID is that of the currently running session (either the logged on identify, or the runas identity).
If you have a local Db2-server with a local database running on MS-Windows, then all necessary software is already installed (if using defaults) to achieve the above.
It is important to understand that if the Db2-database is remote from the client then the authentication will need some form of credentials. Such credentials may be in the form of a certificate (if the Db2-database lives on Z/OS), or in the form of a userid/password, or in the form of a kerberos ticket, or in the form of a token used for cloud-based Db2 etc.
For a passwordless local jdbc connection to a Db2-database , you can use the URL format "jdbc:db2:your_database_name" .
The class com.ibm.db2.jcc.DB2Driver (as supplied in currently supported versions of db2jcc4.jar) supports passwordless connections with that URL pattern.
Example with local database-name = sample.
try
{
Connection con = DriverManager.getConnection("jdbc:db2:sample");
...
}
catch (Exception e)
{
...
}
The Db2 Knowledge-Centre gives all the details of the available jdbc properties
here
https://www.ibm.com/support/knowledgecenter/SSEPGG_11.5.0/com.ibm.db2.luw.apdv.java.doc/src/tpc/imjcc_r0052038.html
Other pages show additional properties that are specific to Z/OS data-sources, or cloud-databases, or i-series data sources, or informix sources etc.

Related

Kerberos on Windows Server out of domain

I want to implement kerberos authentication for a software where both the server and the clients run on Windows and are implemented in C++.
When both, the clients and the server are on the same Windows domain it is straight forward to use SSPI and I assume this will work also for cross-realm environments.
When for any reason the server cannot be member of the domain this straigth forward approach will not work.
How is it possible to achieve Kerberos authentiaction against a server that is not member of the domain?
If my research is correct java applications or linux use a keytab file instead of implicitly retrieving the key from AD. Apparently SSPI does not support keytab files. Is there a way to use keytab files in this scenario?
SSPI does not "retrieve the key from AD" – the service key is always stored locally, but with SSPI it's the machine account password which was generated during AD join process (and uploaded to AD rather than retrieved from) that acts in place of the keytab. Windows stores the machine password in LSA and derives the key from it in memory, but it has the same purpose as a keytab file.
There may be a way to store a machine password in a non-AD machine (using ksetup.exe), but it is very much a system-wide change – it seems to make certain parts of the Windows login process function as if the system was domain-joined – so I would not recommend doing so, except in a test VM.
Instead, you can use another Kerberos implementation – MIT Kerberos and Heimdal are the two major non-AD Kerberos implementations that come in the form of C libraries (both are Windows-compatible, though their focus is on Linux/Unix-like systems). Both libraries provide the GSSAPI interface, which is similar to Windows SSPI, and both use keytab files for service credentials.
For C#, Kerberos.NET is available. For Rust, sspi-rs seems to be in active development (it isn't just a binding to Windows SSPI but a standalone implementation as well). Java of course has its own Kerberos implementation built-in as part of JAAS although Apache Kerby exists as well.
Most of those implementations support the same keytab format because they mimic MIT Kerberos to some extent (which was the original Kerberos 5 implementation).
Both MIT Krb5 and Heimdal include not just a library but a KDC service as well, though that part won't run on Windows. (Kerby and Kerberos.NET could also be used to build minimal KDCs.)
The above is more important for servers; however, a client can use SSPI to authenticate to Kerberos services without any requirement to be a domain member.
For realms that are AD-based (regardless of the specific server being domain-joined or not), it is enough to provide a UPN-format username (in the form of user#domain) and a password to SSPI; it will automatically discover KDCs and obtain tickets.
The same works for Kerberos realms that are not AD-based as long as the realm is marked as a "MIT realm" either via registry or using ksetup /AddRealmFlags. (The principal user#REALM needs to be specified as username in this case.) Unlike the earlier mentioned case, this ksetup.exe usage seems to have no negative side effects.

Connect to kerberised hive using jdbc from remote windows system

I have setup a hive environment with Kerberos security enabled on a Linux server (Red Hat). And I need to connect from a remote windows machine to hive using JDBC.
So, I have hiveserver2 running in the linux machine, and I have done "kinit".
Now I try to connect from a java program on the windows side with a test program like this,
Class.forName("org.apache.hive.jdbc.HiveDriver");
String url = "jdbc:hive2://<host>:10000/default;principal=hive/_HOST#<YOUR-REALM.COM>"
Connection con = DriverManager.getConnection(url);
And I got the following error,
Exception due to: Could not open client transport with JDBC Uri:
jdbc:hive2://<host>:10000/;principal=hive/_HOST#YOUR-REALM.COM>:
GSS initiate failed
What am I doing here wrong ? I checked many forums, but couldn't get a proper solution. Any answer will be appreciated.
Thanks
If you were running your code in Linux, I would simply point to that post -- i.e. you must use System properties to define Kerberos and JAAS configuration, from conf files with specific formats.
And you have to switch the debug trace flags to understand subtile configuration issue (i.e. different flavors/versions of JVMs may have different syntax requirements, which are not documented, it's a trial-and-error process).
But on Windows there are additional problems:
the Apache Hive JDBC driver has some dependencies on Hadoop JARs, especially when Kerberos is involved (see that post for details)
these Hadoop JARs require "native libraries" -- i.e. a Windows port of Hadoop (which you have to compile yourself!! or download from an insecure source on the web!!) -- plus System properties hadoop.home.dir and java.library.path pointing to the Hadoop home dir and its bin sub-dir respectively
On the top of that, the Apache Hive driver has compatibility issues -- whenever there are changes in the wire protocol, newer clients cannot connect to older servers.
So I strongly advise you to use the Cloudera JDBC driver for Hive for your Windows clients. The Cloudera site just asks your e-mail.
After that you have a 80+ pages PDF manual to read, the JARs to add to your CLASSPATH, and your JDBC URL to adapt according to the manual.
Side note: the Cloudera driver is a proper JDBC-4.x compliant driver, no need for that legacy Class.forName()...
The key for us when we ran into the problem, was as follows:
On your server there are certain kerberos principals listed that are allowed to operate on the data.
When we tried to run a query via JDBC, we didn't do the proper kinit on the client side.
In this case the solution is obvious:
On the windows client: do a kinit with the proper account before connecting
String url = "jdbc:hive2://<host>:10000/default;principal=hive/_HOST#<YOUR-REALM.COM>"
You should replace <YOUR-REALM.COM> with your real REALM.

How to sniff Oracle's credentials from a connection attempt to the database?

I have a legacy application, which connects to the configured Oracle database.
It seems it has some logic that alters the database credentials as it is unable to successfully log in to the Oracle database, while sqlplus started on the same machine is able to log in.
The error I am getting is: [DataDirect][ODBC Oracle Wire Protocol driver][Oracle]ORA-01017: invalid username/password; logon denied
How to find out what is the database username and password that are sent to the database?
What I have tried so far:
Enabled auditing of failed sign-on attempts on Oracle (audit create session whenever not successful). It does not solve the issue, because it only logs the username, which seems to be correct, without the password.
Used a sniffer to eavesdrop the network traffic between the machine running the application and the database, but since Oracle's TNS protocol is encrypted, it did not help a lot.
Started a server using netcat on port X, provided port X in the application configuration file. The application did connect to my server, that is how I know the application is connecting to the correct server. But since the TNS protocol is pretty complex (requires a series of messages to be exchanged between the client and the server) I hope there is a simpler why of achiving what I want without having to reverse engineer Oracle and implementing my own server.
Enabled tracing of the JDBC driver (Trace=1, TraceFile, TraceDll). The trace file shows the correct username, but obviously the password is not getting logged.
My environment:
Database: Oracle 11g
Application runs on: Solaris
Application uses: DataDirect ODBC Oracle Wire Protocol v70
I not sure, but if connection established by ODBC driver (as described in question tags) then you can try ODBC sniffing tools like ODBC Tracing.
Citation:
Password "Sniffing" Using Trace
ODBC provides a means for tracing the conversation taking place between the driver and the host database. Used by developers for testing purposes, the tracing feature is designed to help programmers find out exactly what is going on and to help fix problems. However, tracing (also called "sniffing") can be used by nefarious bad guys to retrieve user passwords.
When tracing is enabled, communications with the host are written to a file. This includes the user ID and password, which are captured in plain text.
Update
SQLPlus connects to Oracle with OCI interface, but DataDirect ODBC driver uses it's own proprietary implementation of communication protocol. So, most probable point of failure is driver misconfiguration or incompatibility.
DataDirect provides some tools for ODBC drivers diagnostics, but only option applicable to case described in question is using snoop utility, which acts like a netcat which already tried.
Because connection failed at credential verification stage, the most probable source of error is using localized symbols for user name or password. There are some issues with Oracle authentication process, listed in DataDirect Knowledge Search (search for ORA-01017).
It seems that DataDirect provides two separate version of driver with and without Unicode support, therefore one of possible points of failure is to connecting with non-Unicode version of driver to Unicode version of database and vice verse.
P.S. For now I don't have any experience with DataDirect ODBC driver. So it's only suggestions about possible source of failure.

Can't change sqlnet.ora runtime?

I am trying to setup Kerberos authentication for my Oracle database and I have a situation where I need to maintain different versions of sqlnet.ora for each kerberos user connection. My application is using OCI driver (a single unix process does more than one user connection to the same Oracle database). And I am not able switch sqlnet.ora between user connections using setenv(TNS_ADMIN) call programmatically. I am assuming once the contents of sqlnet.ora gets loaded to process, it remains unchanged for the rest of its life.
Is my case a practical one, has anyone encountered?
When it comes to kerberos, I am not sure why Oracle client restricts the sqlnet.ora to one principal kerberos user. Maybe Oracle does not have a clean support for kerberos as I dont see OCI API's?
Thanks
Srivatsan

Logging into oracle db as a global user

We are trying to shape up an old, 2 tier, Delphi based application. It originally uses database authentication, we'd like to transform the db user accounts to global users, so an OID server could perform the authentication instead of the database.
The Delphi program can no longer log into the database if the account is a global user. I'm trying to understand the login protocol, so far without results.
Similar thing happens with SQLDeveloper, I can't connect as a global user. SQLPlus however works with both kinds of users. We checked the information flow with Wireshark. When the dbserver asks back for a password, the SQLPlus sends it, while the SQLDeveloper doesn't send a password when attempting to connect as a global user.
The client sends the application name too in the login request. Is it possible that we have to store the client app name in the LDAP itself?
To connect to Oracle using OID, application must properly configure OCI (Oracle Call Interface). The data access components (which one ?), you are using, must set OCI_ATTR_DISTINGUISHED_NAME session attribute. If that is not done, then you will be not able to connect to Oracle server using ODI and OCI.
You should check your components documentation for this feature. And if it is not implemented, then discuss this issue with the components vendor. Actually, there is not much work to implement, but some work to setup testing environment is required ...

Resources