Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for connecting with LDAP in Thin Mode #111

Open
mkmoisen opened this issue Dec 7, 2022 · 23 comments
Open

Add support for connecting with LDAP in Thin Mode #111

mkmoisen opened this issue Dec 7, 2022 · 23 comments
Labels
enhancement New feature or request

Comments

@mkmoisen
Copy link

mkmoisen commented Dec 7, 2022

In cx_Oracle, in order to connect to an oracle database over LDAP, we need to create a sqlnet.ora file and ldap.ora file.

In oracledb's thin mode, sqlnet.ora is not supported, and presumably ldap.ora file is not either.

Is it possible to connect over LDAP in oracledb's thin mode?

If so, how do we do it?

@mkmoisen mkmoisen added the question Further information is requested label Dec 7, 2022
@anthony-tuininga
Copy link
Member

Not currently. I can convert this to an enhancement request if you would like. If you can provide any details on your requirements that would be helpful.

@mkmoisen
Copy link
Author

mkmoisen commented Dec 7, 2022

I would appreciate being able to use thin mode if that would be a possibility. We are hoping to get away from needing the instant client as it slows down our ability to upgrade docker images.


In cx_Oracle, I do LDAP connections this way.

sqlnet.ora:

SQLNET.AUTHENTICATION_SERVICES= (NTS)

NAMES.DIRECTORY_PATH= (LDAP, TNSNAMES, EZCONNECT)

For me, I need to put LDAP first, which minimizes the time Oracle spends.

ldap.ora:

DIRECTORY_SERVERS = (myldapserver.host.com:1234)
DEFAULT_ADMIN_CONTEXT = "dc=host,dc=com"
DIRECTORY_SERVER_TYPE = OID

So I suppose I would need some way to tell the thin client to 1) use ldap, 2) provide my ldap servers/ports, I guess this can be a list, as well as the admin context and server type.

@mkmoisen
Copy link
Author

mkmoisen commented Dec 7, 2022

In addition, I noticed that in thick mode, I'm unable to connect over LDAP via:

oracledb.connect(user='myuser', password='mypassword', service_name='mydatabase')

This takes ~5 seconds before failing with:

oracledb.exceptions.DatabaseError: ORA-12545: Connect failed because target host or object does not exist

I can connect without issue over LDAP using dns:

oracledb.connect('myuser/mypassword@mydatabase')

@anthony-tuininga
Copy link
Member

Thanks. I'll change this to an enhancement request. I don't know when this will be implemented though. You have to convince @cjbj that this enhancement is more important than others!

@anthony-tuininga anthony-tuininga added enhancement New feature or request and removed question Further information is requested labels Dec 7, 2022
@anthony-tuininga anthony-tuininga changed the title How to connect over LDAP in Thin Mode? Add support for connecting with LDAP in Thin Mode Dec 7, 2022
@cjbj
Copy link
Member

cjbj commented Dec 7, 2022

'myuser/mypassword@mydatabase'

uses a network service alias, not a service name, so service_name='mydatabase' is not a valid equivalent.
The tnsnames.ora file maps that alias to a descriptor which will contain the actual service name.

@danidorbek
Copy link

i have tried to describe something similar in this discussion with a potential solution. Maybe that helps to speed up.

@ilmarkerm
Copy link

I'd like to add my strong upvote for this enhancement request.

@urosdigital
Copy link

+1

@mkmoisen
Copy link
Author

@anthony-tuininga @cjbj Any chance we can get this feature to add support for connecting with LDAP in thin monde scheduled?

Connecting over LDAP is the preferred way at many companies that use Oracle.

@anthony-tuininga
Copy link
Member

It is on the list of enhancements but there are many other enhancements on the list, too! If you have any compelling arguments why this particular enhancement should have its priority increased I'm sure that @cjbj would love to hear them!

@cjbj
Copy link
Member

cjbj commented Oct 20, 2023

We do have a lot of enhancements to both Thin and Thick that our users want, including features we must add for supporting 23c database features. At least with LDAP there is already a general solution, for better or worse: Thick mode. Send me your "business case" so we can prioritize.

@ilmarkerm
Copy link

@cjbj here is our business case: Currently there is no proper JDBC-compatible alternative for LDAP connections from python. The Thick mode does not support supplying all connection string information from the URL and requires permanently changing ldap.ora file on the deployment container. This prevents automated application deployments, where all the application connection environment is supplied dynamically during deploy, depending on where the application was currently deployed.
We deploy applications automatically in many different environments all over the world, using the same application container and we cannot pre-create the ldap.ora file inside the container, since LDAP servers are different and should be supplied during deploy time - using JDBC driver compatible connection strings (as almost all applications currently use JDBC driver). Currently this issue prevents us from allowing developers to deploy Python applications that they request.

@mkmoisen
Copy link
Author

@cjbj

I would argue that LDAP is the only good way to connect to Oracle and that we should be doing everything we can to incentivize the use of LDAP over TNS. Companies that can pay for Oracle are presumably using RAC and have failover between data centers. LDAP is the best way to handle this configuration as the DBAs can change the individual RAC hosts and the database can failover transparently to applications.

Thick mode today and cx_Oracle in the past have always been inconvenient due to the hard dependency on Oracle Instant Client.

My most recent inconvenience was due to a version incompatibility between a newer version of glibc that our security team wanted us to upgrade to, and a compatible version of libnsl which wasn't available in our companies yum mirror. After spending two days of effort on this, my work around is a Dockerfile that first installs the older version of glibc and libnsl, copies the libnsl.so.1 file, uninstalls libnsl, upgrades glibc, pastes the libnsl.so.1 file into /usr/lib64, and then installs oracle instant client skipping dependencies.

Installing the instant client adds a material amount of time to the container build process.

If someone installs an Oracle Instant Client with mismatched versions, especially major versions, this normally leads to subtle bugs. I can remember one weird bug with timezones - all of the dates that were passed in by the application server were stored in a different timezone on the server. Fun times.

Java programmers have it easier. They don't need oracle instant client, and don't need tnsnames.ora or ldap.ora. They just connect with an ldap string and call it a day. I remember struggling with this as a beginner. I think it took me an entire week to figure out. If you search for "cx_Oracle ldap" in Google you'll find my stackoverflow question from many years ago.

I worry that a lot of beginner programmers would think this is not worth the effort and would just stick with Java.

@cjbj
Copy link
Member

cjbj commented Oct 24, 2023

@ilmarkerm @mkmoisen thanks for comments; it's just a matter of scheduling (+ completing some legal work). Have some patience.

Random points:

  • I have been continuing to champion improving Oracle Call Interface usability for LDAP which should make Thick mode usage easier; there is some progress internally.
  • Instant Client 21+ doesn't need libnsl
  • There is a new centralized config store for cloud being worked on for all language drivers. ODP.Net doc is here and gives a flavor of this project. Python support is not yet scheduled but is one of our 'must dos'

@mkmoisen
Copy link
Author

Hi @cjbj @anthony-tuininga

I tried @danidorbek's workaround here and it appears to work just fine.

All this work around does is manually interrogate the LDAP server to retrieve the TNS string, and then uses the TNS string to connect.

Is this suitable? I'm unclear if thick mode ldap connection does any more than this.

import ldap3
import oracledb

def connect(schema, password, database):
    with ldap3.Connection('my-ldap.com') as conn:
        conn.search('cn=OracleContext,dc=my,dc=com', f"(cn={database})", attributes=['orclNetDescString'])
        tns_string = conn.entries[0].orclNetDescString.value
        print(tns_string)

    return oracledb.connect(f'{schema}/{password}@{tns_string}')

@cjbj
Copy link
Member

cjbj commented Oct 26, 2023

We haven't done any serious investigation yet either so I can't comment. (Anthony is working hard on this and this - let's not distract him!)

@cjbj
Copy link
Member

cjbj commented Oct 27, 2023

A question from our team looking at the OCI improvements: what authentication, if any, are you using for LDAP? (cc @mkmoisen @ilmarkerm @danidorbek @urosdigital )

@mkmoisen
Copy link
Author

@cjbj we don't use authentication for the ldap server.

@ilmarkerm
Copy link

@cjbj we don't use authentication either

@danidorbek
Copy link

danidorbek commented Oct 28, 2023 via email

@urosdigital
Copy link

@cjbj sorry for late response, no auth also

@cjbj
Copy link
Member

cjbj commented Oct 30, 2023

Thanks for all the feedback I'll pass it on - including the note that doc on authentication could be enhanced or otherwise we should explain the options better.

A couple of random references re authentication:

@cjbj
Copy link
Member

cjbj commented Dec 3, 2023

Also see #71 (reply in thread)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants