Databases, Kerberos, MS-SQL Server

MS-SQL: connecting Python on Linux – using Active Directory Credentials and Kerberos

Read Time:7 Minute, 19 Second

Last Updated on July 13, 2023 by Hammad Rauf

Microsoft SQL Server (MS-SQL) is a very popular database server. Following the 3-tier architecture many applications use it as the back end database server. Apart from Microsoft Windows based applications sometimes the application are deployed on Linux servers. What is required when connecting a Python Application (on Linux) to a MS-SQL back-end using Windows (Active Directory Domain) user account? After some searching on the Internet a solution was found that allowed this possibility.

Following is a summary of what is needed in order to accomplish this connection between a Python application running on Linux and MS-SQL back-end using Active Directory user account credentials. The contents below are based on several different web-sites where parts of the solution were discovered. These steps have been verified on CentOS Linux 6.8 (RHEL 6.8). I have collected all the steps in one article.

Installing MS-SQL Driver (Pyodbc and Microsoft ODBC SQL Driver)

It turns out that it is not possible to use “pymssql” to connect using Active Directory user account on Linux Centos 6.8 (RHEL 6.8). The pymssql python driver library only supports MS-SQL user accounts. So for this problem we had to use “pyodbc” with Microsoft provided ODBC SQL Driver.

To install “pyodbc” and MS ODBC SQL Driver use the following steps.

sudo yum install gcc-c++
sudo yum install python-devel
sudo yum install python-pip
sudo yum install unixODBC-devel
sudo pip install pyodbc # failed
OR
sudo yum install pyodbc

Now as root or Super User type the following. This will update the “yum” repositories list to include Microsoft published RHEL software site.

sudo su
curl https://packages.microsoft.com/config/rhel/6/prod.repo > /etc/yum.repos.d/mssql-release.repo
exit

Now type the following to download the MS ODBC SQL Server driver. There are some optional components that you may find useful. These steps also update the $PATH environment variable to include the optional tools.

sudo yum remove unixODBC-utf16 unixODBC-utf16-devel
sudo ACCEPT_EULA=Y yum install msodbcsql
sudo ACCEPT_EULA=Y yum install mssql-tools # optional
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
sudo yum install unixODBC-devel # optional

Use the following steps to verify that the pyodbc and MS-ODBC SQL Driver installed correctly.

ls -l /usr/lib64/libodbc*
odbc_config --version --longodbcversion --cflags --ulen --libs --odbcinstini --odbcini
odbcinst -j
isql --version
ls -l /opt/microsoft/msodbcsql/lib64/
dltest /opt/microsoft/msodbcsql/lib64/libmsodbcsql-11.0.so.2270.0 SQLGetInstalledDrivers
dltest /opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9.0 SQLGetInstalledDrivers
cat /etc/odbcinst.ini # should contain a section called [ODBC Driver 13 for SQL Server]

Connecting Via DSN

You may want to create a Data Source Name (DSN) to connect to the database. If that is the case then create a text file with the following contents and save it as “myconnection_dsn_stub.dsn”.

[MyDSNName]
Driver      = ODBC Driver 13 for SQL Server
Description = My Database DSN
Trace       = No
Server      = db_server.mycontoso.com,1433

Now register the DSN entry and test connection in Python. Note that “Trusted connection = yes” forces the driver to use Active Directory (Kerberos) user account.

cat /etc/odbcinst.ini
sudo odbcinst -i -s -f ./mycnonection_dsn_stub.dsn -l
cat /etc/odbc.ini
python -c "import pyodbc; print(pyodbc.connect('DSN=MyDSNName;DATABASE=db_name;UID=ad_user_id;PWD=*****;Trusted_Connection=yes'))"

If you have not installed and configured Kerberos (See below) then you will get following error message.

Traceback (most recent call last):
File "", line 1, in
pyodbc.Error: ('HY000', "[HY000] [unixODBC][Microsoft][ODBC Driver 13 for SQL Server]SSPI Provider: Credentials cache file '/tmp/krb5cc_500' not found (851968) (SQLDriverConnectW)")



Install Kerberos

Linux servers use Kerberos to work with Microsoft Windows Active Directory Domain servers. Kerberos provides a reliable and secure way for Linux servers to authenticate on Active Directory domains.

Install Kerberos by using the following steps.

sudo yum install krb5-workstation
cat /etc/krb5.conf

To configure Kerberos to work in your Active Directory domains, you need to configure it. On a Windows Desktop computer perform the following steps to find out the Domain controller server name. Replace DOMAIN_NAME with actual domain name i.e. contoso.com .

C:\> nslookup
> set type=all
> _ldap._tcp.dc._msdcs.MYCONTOSO.COM
mycontoso.com nameserver = my-domain-controller-server.MYCONTOSO.com
......................
ping my-domain-controller-server.MYCONTOSO.com

Now configure Kerberos as follows. Please note that the contents of “/etc/krb5.conf” file are shown as “cat” command output.

sudo cp /etc/krb5.conf /etc/krb5.conf_backup
ls -l /etc/krb5*
sudo vi /etc/krb5.conf
cat /etc/krb5.conf
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log

[libdefaults]
default_realm = MYCONTOSO.COM

[realms]
MYCONTOSO.COM = {
kdc = my-domain-controller-server.MYCONTOSO.com
}

[domain_realm]
.mycontoso.com = MYCONTOSO.COM
mycontoso.com = MYCONTOSO.COM

Kerberos works by passing the user account and password information to Active Directory server, which authenticates the user. If the user is authenticated successfully then a temporary Kerberos Ticket is saved in “/tmp/krb5cc” file. This ticket can be used to login to Windows Servers before the ticket expires.

To obtain Kerberos Ticket interactively, for testing the connection type the following commands.

kinit AD_USER_ID@MYCONTOSO.COM
# Enter User Password

klist  # Lists Kerberos Tickets
# Ticket cache: FILE:/tmp/krb5cc_500
# Default principal: AD_USER_ID@MYCONTOSO.COM
#
# Valid starting Expires Service principal
# 08/31/17 14:17:29 09/01/17 00:17:50 krbtgt/MYCONTOSO.COM@MYCONTOSO.COM
# renew until 09/01/17 14:17:29
# 08/31/17 14:18:56 09/01/17 00:17:50 MSSQLSvc/db_server.mycontoso.com:1433@MYCONTOSO.COM
# renew until 09/01/17 14:17:29

Connecting Python With Kerberos Ticket

To test Connection with current Kerberos ticket type the following. Please note that this connection method is not using the DSN that we created earlier.

$ cat testConnection.py
import pyodbc
cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};SERVER=db_server.mycontonso.com,1433;DATABASE=db_name;Trusted_Connection=yes')
cursor = cnxn.cursor()
cursor.execute('SELECT TOP 10 [ServerName],[RunID],[JobID],[TimeStamp] FROM [db_name].[dbo].[table_name] ORDER BY [RunID] DESC')
row = cursor.fetchone()
if not row:
print("No rows returned.")
while row:
print("ServerName=%s, JobID=%d, TimeStamp=%s" % (row[0], row[2], row[3]))
row = cursor.fetchone()
cnxn.close()

$ python testConnection.py

Following is an example of how Python code can be used to obtain fresh Kerberos ticket and then connect to the MS-SQL database back-end.

from subprocess import Popen, PIPE
import pyodbc

# Login Credentials
userid="AD_USER_ID"
password='******'
realm="MYCONTOSO.COM"
kinit = '/usr/bin/kinit'

# Get Fresh Kerberos Ticket
kinit_args = [ kinit, '%s@%s' % (userid, realm) ]
kinit = Popen(kinit_args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
kinit.stdin.write('%s\n' % password)
kinit.wait()

cnxn = pyodbc.connect('DRIVER={ODBC Driver 13 for SQL Server};SERVER=db_server.mycontoso.com,1433;DATABASE=db_name;Trusted_Connection=yes')
cursor = cnxn.cursor()
cursor.execute('''SELECT TOP 10 CAST([ServerName] AS VARCHAR) AS SERVERNAME
,[RunID]
,[JobID]
,CAST([LongText] AS VARCHAR(MAX)) AS LONGTEXT
,[TimeStamp]
FROM [db_name].[dbo].[table_name]''')
row = cursor.fetchone()
if not row:
print("No rows returned.")
while row:
print("ServerName=%s, LongText=%s, JobID=%d, TimeStamp=%s" % (row[0], row[3], row[2], row[4]))
row = cursor.fetchone()
cnxn.close()
Is this content useful for you? Support this site by donating any amount....(takes you to Paypal website)
Other Amount

Further Reading

The following list is not complete, but it provides some pointers for further reading on the topics discussed in this article.

    1. Python Kerberos Kinit – https://pypi.python.org/pypi/kerberos , Date accessed: September 26, 2017
    2. Python Kerberos – http://python-notes.curiousefficiency.org/en/latest/python_kerberos.html , Date accessed: September 26, 2017
    3. CentOS Home page- https://wiki.centos.org/FrontPage , Date accessed: September 26, 2017
    4. Three Tier Architecture – https://en.wikipedia.org/wiki/Multitier_architecture#Three-tier_architecture , Date accessed: September 26, 2017
    5. Kerberos Reference – https://web.mit.edu/kerberos/ , Date accessed: September 26, 2017
    6. pyodbc Driver/Bridge – https://mkleehammer.github.io/pyodbc/ , Date accessed: September 26, 2017
    7. Microsoft ODBC SQL Driver installation – https://docs.microsoft.com/en-us/sql/connect/python/pyodbc/step-1-configure-development-environment-for-pyodbc-python-development , Date accessed: September 26, 2017
    8. Microsoft ODBC Driver installation 2 – https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server , Date accessed: September 26, 2017
    9. Active Directory – https://en.m.wikipedia.org/wiki/Active_Directory , Date accessed: September 26, 2017