Anaconda3's python cannot find kerberos credential cache - python

I run into an error when creating an ODBC connection to a MSSQL server using Anaconda's version of Python 3:
pyodbc.Error: ('HY000', '[HY000] [Microsoft][ODBC Driver 17 for SQL Server]SSPI Provider: No Kerberos credentials available (default cache: KEYRING:persistent:1918003883) (851968) (SQLDriverConnect)')
The server has joined a Windows Active Directory domain and Kerberos realm via SSSD. I can SSH into the server, and retrieve a TGT using kinit. I can even see the credential cache with klist. But the python process cannot seem to either find the Kerberos TGT or the Kerberos credential cache.
the setup:
python
$ /mnt/ds/anaconda3/bin/python --version
Python 3.6.5 :: Anaconda, Inc.
test.py
from pyodbc import connect
connection = connect('DSN=MyDSN')
/etc/odbc.ini
[MyDSN]
#Driver=ODBC Driver 13 for SQL Server
Driver=ODBC Driver 17 for SQL Server
Description=MyMSSQL ODBC Driver
Trace=No
Server=MyMSSQL
Trusted_Connection=Yes
/etc/odbcinst.ini
[ODBC Driver 17 for SQL Server]
Description=Microsoft ODBC Driver 17 for SQL Server
Driver=/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.1.so.0.1
UsageCount=1
Red Hat Enterprise Linux
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.5 (Maipo)
$ uname -r
3.10.0-862.2.3.el7.x86_64
msodbcsql17
$ sudo yum info msodbcsql17
Loaded plugins: amazon-id, rhui-lb, search-disabled-repos
Installed Packages
Name : msodbcsql17
Arch : x86_64
Version : 17.1.0.1
Release : 1
Size : 17 M
Repo : installed
From repo : packages-microsoft-com-prod
Summary : ODBC Driver for Microsoft(R) SQL Server(R)
License : https://aka.ms/odbc170eula
Description : This package provides an ODBC driver that can connect to Microsoft(R) SQL Server(R).
unixODBC
$ sudo yum info unixODBC
Loaded plugins: amazon-id, rhui-lb, search-disabled-repos
Installed Packages
Name : unixODBC
Arch : x86_64
Version : 2.3.1
Release : 11.el7
Size : 1.2 M
Repo : installed
From repo : rhui-REGION-rhel-server-releases
Summary : A complete ODBC driver manager for Linux
URL : http://www.unixODBC.org/
License : GPLv2+ and LGPLv2+
Description : Install unixODBC if you want to access databases through ODBC.
: You will also need the mysql-connector-odbc package if you want to access
: a MySQL database, and/or the postgresql-odbc package for PostgreSQL.
$ /mnt/ds/anaconda3/bin/conda list unixodbc
# packages in environment at /mnt/ds/anaconda3:
#
# Name Version Build Channel
unixodbc 2.3.6 h1bed415_0
pyodbc
$ /mnt/ds/anaconda3/bin/conda list pyodbc
# packages in environment at /mnt/ds/anaconda3:
#
# Name Version Build Channel
pyodbc 4.0.23 py36hf484d3e_0
Here are some things I've tried:
Using Python-2.7.15, as packaged by Anaconda2. That worked!
Using isql. I ran isql MyDSN and that connected.
There are two unixODBC libraries (one installed via yum; the other with conda). By default, it will use conda's, but I forced it to use the system unixODBC package with LD_PRELOAD. Same error.
I tried downgrading the database driver to msodbcsql-13.1.9.2-1 and then to msodbcsql-13.0.1.0-1. Same error.
I tried swapping out PyODBC for TurbODBC, another Python ODBC library. Same error.
I created a separate environment in conda with python-3.5. And that worked! Still not sure why.
I wrote a simple C program that interfaced with unixODBC. That program was able to connect to the MSSQL server via Kerberos just fine.
I ran the python2 positive test case and the python3 negative test case through strace to review the system calls. I thought that might reveal something. It seems that they both start looking for the client.keytab file on the file system. Then, in the postive test case, it will fallback to searching the kernel's keyring, where it will successfully find the credential cache and proceed. However, in the negative test case, it simply retries to find client.keytab, and never attempts to search the keyring.
I enabled the unixODBC trace option, one with Python3 test case, and the other with Python2 test case. Unfortunately, the traces (shown below) don't reveal anything to me.
py3-unixodbc.trace
[ODBC][8741][1527046794.480751][__handles.c][460]
Exit:[SQL_SUCCESS]
Environment = 0x55eea73ed130
[ODBC][8741][1527046794.480806][SQLSetEnvAttr.c][189]
Entry:
Environment = 0x55eea73ed130
Attribute = SQL_ATTR_ODBC_VERSION
Value = 0x3
StrLen = 4
[ODBC][8741][1527046794.480824][SQLSetEnvAttr.c][363]
Exit:[SQL_SUCCESS]
[ODBC][8741][1527046794.480843][SQLAllocHandle.c][375]
Entry:
Handle Type = 2
Input Handle = 0x55eea73ed130
[ODBC][8741][1527046794.480861][SQLAllocHandle.c][493]
Exit:[SQL_SUCCESS]
Output Handle = 0x55eea7400500
[ODBC][8741][1527046794.481176][SQLDriverConnectW.c][290]
Entry:
Connection = 0x55eea7400500
Window Hdl = (nil)
Str In = [DSN=MyDSN][length = 15]
Str Out = (nil)
Str Out Max = 0
Str Out Ptr = (nil)
Completion = 0
UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'
[ODBC][8741][1527046794.575566][__handles.c][460]
Exit:[SQL_SUCCESS]
Environment = 0x55eea746e360
[ODBC][8741][1527046794.575614][SQLGetEnvAttr.c][157]
Entry:
Environment = 0x55eea746e360
Attribute = 65002
Value = 0x7ffd399177f0
Buffer Len = 128
StrLen = 0x7ffd3991778c
[ODBC][8741][1527046794.575632][SQLGetEnvAttr.c][264]
Exit:[SQL_SUCCESS]
[ODBC][8741][1527046794.575651][SQLFreeHandle.c][219]
Entry:
Handle Type = 1
Input Handle = 0x55eea746e360
py2-unixodbc.trace
[ODBC][8746][1527046842.073439][__handles.c][460]
Exit:[SQL_SUCCESS]
Environment = 0x185e2e0
[ODBC][8746][1527046842.073530][SQLSetEnvAttr.c][189]
Entry:
Environment = 0x185e2e0
Attribute = SQL_ATTR_ODBC_VERSION
Value = 0x3
StrLen = 4
[ODBC][8746][1527046842.073552][SQLSetEnvAttr.c][363]
Exit:[SQL_SUCCESS]
[ODBC][8746][1527046842.073572][SQLAllocHandle.c][375]
Entry:
Handle Type = 2
Input Handle = 0x185e2e0
[ODBC][8746][1527046842.073590][SQLAllocHandle.c][493]
Exit:[SQL_SUCCESS]
Output Handle = 0x1857d40
[ODBC][8746][1527046842.073613][SQLDriverConnectW.c][290]
Entry:
Connection = 0x1857d40
Window Hdl = (nil)
Str In = [DSN=MyDSN][length = 15]
Str Out = (nil)
Str Out Max = 0
Str Out Ptr = (nil)
Completion = 0
UNICODE Using encoding ASCII 'ISO8859-1' and UNICODE 'UCS-2LE'
[ODBC][8746][1527046842.208760][__handles.c][460]
Exit:[SQL_SUCCESS]
Environment = 0x1967210
[ODBC][8746][1527046842.208830][SQLGetEnvAttr.c][157]
Entry:
Environment = 0x1967210
Attribute = 65002
Value = 0x7ffe1153fcf0
Buffer Len = 128
StrLen = 0x7ffe1153fc8c
[ODBC][8746][1527046842.208849][SQLGetEnvAttr.c][264]
Exit:[SQL_SUCCESS]
[ODBC][8746][1527046842.208869][SQLFreeHandle.c][219]
Entry:
Handle Type = 1
Input Handle = 0x1967210
Suffice it to say, I'm at my wit's end. Any ideas would be greatly appreciated!

late reply but I hope someone will find it useful.
This very same issue for me was casued by the krb5 package which was coexisting with the system-wide kerberos installation: removing it from the environment solved the problem (I tried to make it work but had no success).

Related

[ODBC Driver 17 for SQL Server]SSL Provider: [error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol]

os: ubuntu 20.04
server SQL server version: Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (Intel X86)
python 3.8
import pyodbc
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
Error:
[Microsoft][ODBC Driver 17 for SQL Server]SSL Provider: [error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol] (-1) (SQLDriverConnect)')
I try to modify openssl.conf:
oid_section = new_oids
openssl_conf = default_conf
[default_conf]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
MinProtocol = TLSv1.1
CipherString = DEFAULT#SECLEVEL=1
then reboot
but it cant work.
This might be the right approach, but I think you should lower the protocol to TLSv1.0
[system_default_sect]
MinProtocol = TLSv1.0
CipherString = DEFAULT#SECLEVEL=1
I just hit this problem trying to connect from a Debian 10 with openssl 1.1.1d to a Windows Server 2008 with MSSQL 12 Express.
Lowering the protocol version works directly, no reboot needed.
step1:
nano /etc/ssl/openssl.cnf
# Extra OBJECT IDENTIFIER info:
#oid_file = $ENV::HOME/.oid
oid_section = new_oids
openssl_conf = default_conf
[default_conf]
ssl_conf = ssl_sect
[ssl_sect]
system_default = system_default_sect
[system_default_sect]
MinProtocol = TLSv1.0
CipherString = DEFAULT#SECLEVEL=1
step2:
The manual installation looks like:
wget https://www.openssl.org/source/latest.tar.gz -O openssl-1.1.1h.tar.gz
tar -zxvf openssl-1.1.1h.tar.gz
cd openssl-1.1.1h
./config
make
sudo make install
openssl version
sudo ldconfig
reference:
https://askubuntu.com/questions/1284658/how-to-fix-microsoft-odbc-driver-17-for-sql-server-ssl-provider-ssl-choose-cli
This issue can be fixed by installing this security update from Microsoft:
Security Update for SQL Server 2008 R2 SP3 (KB4057113)
Look for 1.1.1m.tar.gz - this is the latest.

How do I fix connection to db2 using SQLAlchemy in python?

I'm having trouble connecting to my database BLUDB in IBM Db2 on Cloud using SQLAlchemy. Here is the code I've always used and it's always worked fine:
%sql ibm_db_sa://user:pswd#some-host.services.dal.bluemix.net:50000/BLUDB
But now I get this error:
(ibm_db_dbi.ProgrammingError) ibm_db_dbi::ProgrammingError:
Exception('[IBM][CLI Driver] SQL1042C An unexpected system error
occurred. SQLSTATE=58004\r SQLCODE=-1042') (Background on this error
at: http://sqlalche.me/e/13/f405) Connection info needed in SQLAlchemy
format, example: postgresql://username:password#hostname/dbname or an
existing connection: dict_keys([])
These packages are loaded as always:
import ibm_db
import ibm_db_sa
import sqlalchemy
from sqlalchemy.engine import create_engine
I looked at the python db2 documentation on ibm and the sqlalchemy error message but couldn't get anywhere.
I am working in Jupyterlab locally. I've recently reinstalled Python and Jupyterlab. That's the only thing locally that's changed.
I am able to successfully run the notebooks in the cloud at kaggle and cognitive class. I am also able to connect and query sqlite3 via python without an issue using my local notebook.
All the ibm modules and version numbers are the same before and after installation. I used requirements.txt for reinstallation.
In db2diag.log here are the last two entries:
2020-11-05-14.06.47.081000-300 I13371F372 LEVEL: Warning
PID : 17500 TID : 7808 PROC : python.exe
INSTANCE: NODE : 000
HOSTNAME: DESKTOP-6FFFO2E
EDUID : 7808
FUNCTION: DB2 UDB, bsu security, sqlexLogPluginMessage, probe:20
DATA #1 : String with size, 43 bytes
loadAuthidMapper: GetModuleHandle rc = 126
2020-11-05-14.13.49.282000-300 I13745F373 LEVEL: Warning
PID : 3060 TID : 12756 PROC : python.exe
INSTANCE: NODE : 000
HOSTNAME: DESKTOP-6FFFO2E
EDUID : 12756
FUNCTION: DB2 UDB, bsu security, sqlexLogPluginMessage, probe:20
DATA #1 : String with size, 43 bytes
loadAuthidMapper: GetModuleHandle rc = 126
I think the root of this will be down to the new version of Python and pip caching.
What version did you move from and what version are you now on. Is this a Python 2 to Python 3 change? When changing versions, normally you would need to clean pip install all components, but pip does use a cache. Even for components that may need to be compiled, and there is a good chance that Db2 components are being compiled.
So what you will need to do is to re-install the dependancies with
pip install --no-cache-dir

Python 3.4 - Sybase ASE connection

I would like to connect to a Sybase Ase 15 db with Python. Unfortunately I couldnt find any working solution for Windows with Python 3.4. Could anyone refer something? I tried with a few without luck. Can I use OleDb driver (dll) maybe somehow?
It would be great something free which is updated recently. I found solutions from 2012, but there werent working either.
Thank you.
You could use pyodbc:
import pyodbc
DbConnection = pyodbc.connect('DRIVER=freetds;SERVER=%s;PORT=%s;UID=%s;PWD=%s;DATABASE=%s;TDS _Version=5.0;' % (self.ServerAddress, self.ServerPort,
'aselogin', 'loginpwd', DefaultDb),unicode_results=True,autocommit=True)
Prerequisite: installing the driver FreeTDS corresponding to your OS.
First of all I want to point out the following: we can't connect to the Sybase ASE database just using Python; we have to use an external binary (called driver) which is able to manage the connections. In my case, I connect from a Windows machine using "jconn4.jar" driver.
In order to get the driver (jconn4.jar) I had to install Dbeaver application., and I set up a connection to the Sybase database that I want to access via python.
The next step is to test the connection and get the connection parameters. Press Test Connection --> Details.
In the windows that popped up we have all the details we need to configure the Sybase connection from python.
import jaydebeapi
server = "<server IP>"
username = "<username>"
password = "<password>"
database = "<datamase/schema>"
port = <port>
jdbc_driver = r'..\DBeaverData\drivers\drivers\sybase\jconnect\jconn4.jar' // this is the driver path; the path is obtained from the details window
conn = jaydebeapi.connect('com.sybase.jdbc4.jdbc.SybDriver', f'jdbc:sybase:Tds:{server}:{port}/{database}', {'user': username, 'password': password},
jdbc_driver)
cursor = conn.cursor()
cursor.execute("select * from my_table")
result = cursor.fetchall()
print(result)
If you get an error, regarding "JAVA_HOME" is missing
Check JDK is installed on your machine (I have installed JDK 1.8.0_202)
--> If not; install JDK
Add java path to the Environment Variables --> System Variables --> Path --> Edit --> New and paste the path to the Java bin folder (C:\Program Files\Java\jdk1.8.0_202\bin) --> Press OK
Specify the JAVA_HOME environment variable; Environment Variables --> System Variables --> New --> Varialbe Name: JAVA_HOME, Varialbe Value: C:\Program Files\Java\jdk1.8.0_202

Create a DSN for pyodbc similar to PHP PDO. Is it possible?

I use PHP PDO to connect a MySql Db and it works great. I have something like:
$dsn = 'mysql:host=localhost;dbname=database_name';
$user_db = 'admin';
$password = 'password';
$pdo = new PDO($dsn, $user_db, $password);
Now I need to load same database from a python script and I have to use pypodbc module
But I'm getting some issue:
If I do (on Python):
pyodbc.connect('DRIVER={MySQL};SERVER=localhost;DATABASE=database_name;UID=admin;PWD=password;')
I got en error on log:
pyodbc.Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open
lib '/usr/lib64/libmyodbc5.so' : file not found (0)
(SQLDriverConnect)")
If i check the /etc/odbcinst.ini i can see:
# Driver from the mysql-connector-odbc package
# Setup from the unixODBC package
[MySQL]
Description = ODBC for MySQL
Driver = /usr/lib/libmyodbc5.so
Setup = /usr/lib/libodbcmyS.so
Driver64 = /usr/lib64/libmyodbc5.so
Setup64 = /usr/lib64/libodbcmyS.so
FileUsage = 1
I tried to add the the package mysql-connector-odbc by YUM and i got mysql-connector-odbc.x86_64 0:5.1.5r1144-7.el6
And then running my script I got a new error:
/usr/local/bin/python2.7: relocation error: /usr/lib64/libmyodbc5.so: symbol strmov, version libmysqlclient_16 not defined in file libmysqlclient_r.so.16 with link time reference
It seems this version is not compatible with MySql which I have: 5.5.37-cll - MySQL Community Server (GPL)
I did a YUM REMOVE to restore previous conf.
And now ? Any suggestions ? Thanks!
My configuration:
My Server: CENTOS 6.6 x86_64 virtuozzo
MySql: 5.5.37-cll - MySQL Community Server (GPL)
Finally I fixed it!
yum install unixODBC-devel
yum install mysql-connector-odbc
yum install openssl098e
and than:
rpm -ivh libmysqlclient16-5.1.69-1.w5.x86_64.rpm
Now the
pyodbc.connect('DRIVER={MySQL};SERVER=localhost;DATABASE=database_name;UID=admin;PWD=password;')
works!! yeah!

Problems connecting with Teradata database using pyodbc

Currently, I'm running a simple python script to connect to a database:
import pyodbc
cnxn = pyodbc.connect('DRIVER={Teradata};DBCNAME=(MYDB);UID=(MYUSER); PWD=(MYPASS);QUIETMODE=YES')
With the server and credentials substituted in obviously. However, when running this script, I get the following error:
pyodbc.Error: ('200', '[200] [unixODBC][eaaa[DCTrdt rvr o nuhifraint o n (0) (SQLDriverConnectW)')
The only help I've been able to find is here installed the Teradata ODBC drivers, but I just don't understand why I can't connect. Anyone have any ideas on this?
You have to use like following to connect:
TDCONN = pyodbc.connect('DSN=yourDSNname;',ansi=True, autocommit=True)
You can replace DSN=yourDSNname; with what you have already.
I hit this "non english" error message problem. I think it was due to the wrong versions of libodbc.so and libodbcinst.so being used. Changing the links in /usr/lib/... to point to the teradata installed versions worked for me. Commands using the default install directories in Ubuntu 12.04, 64bit were:
cd /usr/lib/x86_64-linux-gnu
ls -lha | grep odbc (To should see the files below which are to be replaced).
sudo mv libodbc.so.1.0.0 Xlibodbc.so.1.0.0
sudo ln -s /opt/teradata/client/14.10/odbc_64/lib/libodbc.so libodbc.so.1.0.0
sudo mv libodbcinst.so.1.0.0 Xlibodbcinst.so.1.0.0
sudo ln -s /opt/teradata/client/14.10/odbc_64/lib/libodbcinst.so libodbcinst.so.1.0.0
I had also previously installed (through apt-get) odbcinst, so I redirected both files. But possibly only the first is needed.

Categories

Resources