PEPPLER.ORG
Michael Peppler
Sybase Consulting
Menu
Home
Sybase on Linux
Install Guide for Sybase on Linux
General Sybase Resources
General Perl Resources
Freeware
Sybperl
Sybase::Simple
DBD::Sybase
BCP Tool
Bug Tracker
Mailing List Archive
Downloads Directory
FAQs
Sybase on Linux FAQ
Sybperl FAQ
Personal
Michael Peppler's resume

sybperl-l Archive

Up    Prev    Next    

From: Merijn Broeren <merijnb at iloquent dot com>
Subject: Proposal: Adding kerberos support to Sybase libraries
Date: Dec 1 2003 5:34PM

Hello,

I'm interested in adding Kerberos support to the Perl Sybase
modules. I've got a proof of concept working and have been talking with
Michael off list and he suggested we open the discussion to a broader
audience. 

The principle of Kerberos support is simple. You just ask the Sybase
libraries to use a kerberos ticket instead of a username/password
combination when making a connection. In C this code is used:

if (imp_dbh->kerberosPrincipal[0] == 0)
    /* normal login with username and password */
} else {
    /*
    ** If we're using Kerberos, set the appropriate connection properties
    ** (which requires the Sybase Kerberos principal name).  
    */
    buffer = CS_TRUE;
    warn( imp_dbh->kerberosPrincipal);
    if ((retcode = ct_con_props(connection, CS_SET, CS_SEC_NETWORKAUTH,
                            (CS_VOID *) &buffer, CS_UNUSED, NULL)) != CS_SUCCEED) 
    {
        warn("ct_con_props(CS_SEC_NETWORKAUTH) failed");
        return 0;
    }
        
    if ((retcode = ct_con_props(connection, CS_SET, CS_SEC_SERVERPRINCIPAL, 
                   imp_dbh->kerberosPrincipal, CS_NULLTERM, NULL)) != CS_SUCCEED) 
    {
        warn("ct_con_props(CS_SEC_SERVERPRINCIPAL) failed");
        return 0;
    }
}

To make a connection with kerberos you need to set the
CS_SEC_NETWORKAUTH property on the connection. After you've done that
you need to provide the kerberos principal name of the server that you
are connecting to. Normally we connect using a logical server name like
NYTIBV3T026 or NYP_GFS11 so there needs to be a translation from this
to the kerberos principal. To translate to hostname and port we use the
interfaces file, but this does not provide the kerberos information
alas.

At our firm we have this translation table available to us in
a file. I assume other firms will have other ways of doing this lookup,
like an LDAP service or similar.

With the C code as seen above a developer can now request a kerberos
connection by doing the following in their Perl program :

    use sybGetPrinc  qw( sybGetPrinc );
    my $kerbprincipal = sybGetPrinc($Srv);

    my $dbh = DBI->connect(
	"dbi:Sybase:server=$Srv;kerberos=$kerbprincipal;database=$Db;", 
	undef, undef, {PrintError=>1});

In the DBD::Sybase C code (dbdimp.c) I've made the following changes in
addition to the already shown code to extract the principal from the
DSN:

    imp_dbh->kerberosPrincipal[0]  = 0; /* Default to not using network
authentication */

    extractFromDsn("kerberos=", dsn, imp_dbh->kerberosPrincipal, 32);

And in dbdimp.h I've added this field to the struct for the database
handle:

    char      kerberosPrincipal[32];

This is now working for me.

The issue that I want a broader opinion is how this can be made more
generic. I think almost everybody will need to do some sort of lookup. 
The above design will work, but every developer will need to add the
lookup code to his Perl program and then provide the kerberos principal
name in the DSN. 

Another method would be to have a plugin, in either Perl or C that is
added to the configure and build phase of DBD::Sybase. This would then
be used in the login method, for instance if in the DSN we find 
usekerberos=1 or some similar flag. I've talked with Michael about it
and he thinks it would be fruitful if we opened up the discussion a bit. 

Regards,
-- 
Merijn Broeren | My hat to keep the Martian brain rays out works just fine.
Software Geek  | It's really *good* tin foil.
               | And stop staring at me like that.