This discussion is archived
12 Replies Latest reply: Feb 5, 2013 4:06 PM by Alex_Keh - Oracle_Product_Manager RSS

LDAP lookup using managed ODP.NET fails in C# application

987532 Newbie
Currently Being Moderated
I'm using ODP.NET, Managed Driver Beta (Oracle.ManagedDataAccess.dll) in my C# application to access an Oracle database. This is to replace using the native version of ODP.NET in order to remove all the local dependencies on Oracle Client 10g/11g/etc. so that this needn't have to be installed locally. This is a solution I found here: http://stackoverflow.com/a/13970965/197591

This is my C# code:

-----
new OracleConnection("Data Source=ABCDEFG1;User Id=myuserid;Password=mypassword;").Open();
-----

This line is reached and the OracleConnection object is created successfully thereby suggesting all dependencies are loaded successfully. However, it throws an OracleException on the call to Open(). The error message is:

-----
Network Transport: Unable to resolve connect hostname
-----

My organisation performs hostname lookups using LDAP and this is done via the ORA files using DIRECTORY_SERVER setting. However, I'm having difficulty getting it to do this using the managed version of ODP.NET. The ORA files are stored in C:\Apps\oracle\network\admin.

tnsping on my data source ('ABCDEFG1') works fine. So, I used the output of tnsping and added an entry for ABCDEFG1 in tnsnames.ora using this output. My application then connected successfully. So, I know that it is definitely finding and using the ORA files, but, for some reason, it won't perform the LDAP lookup that non-managed ODP.NET (in other applications) uses.

Is anyone who's used this new managed ODP.NET aware of this problem or what I might be doing wrong?

Thanks,
Jason
  • 1. Re: LDAP lookup using managed ODP.NET fails in C# application
    Tridus Journeyer
    Currently Being Moderated
    The managed provider doesn't support LDAP, as per the release notes: http://www.oracle.com/technetwork/database/windows/downloads/odpmbetainstall-1696475.html

    "Note: Only SQL*Net and Easy Connect naming are supported. There is no LDAP/Active Directory support."
  • 2. Re: LDAP lookup using managed ODP.NET fails in C# application
    987532 Newbie
    Currently Being Moderated
    Ah, that would explain it then - thanks!

    Unfortunately, I don't have the option of changing the tnsnames.ora file or any of the other ORA files permanently (I can do it locally, but these files are centrally controlled and deployed to devs' and users' PCs).

    So, is there any way I can get around this issue (somehow getting what I need via LDAP) without changing the ORA files and without hardcoding the connection string in my application?

    In any case, is there any plan for managed ODP.NET to support LDAP in the future?

    Thanks.
  • 3. Re: LDAP lookup using managed ODP.NET fails in C# application
    Tridus Journeyer
    Currently Being Moderated
    I have no idea when/if LDAP support is coming. Maybe Alex can chime in on that.

    For TNS, the managed provider does support a TNS_ADMIN parameter in your app config. You could create a new tnsnames.ora file for the managed provider, stick it somewhere central (like on a mapped drive) and point the managed client at it.

    It might also be possible to have your application itself query LDAP and then set the connection string to whatever the result comes back as, but that seems like a lot of hassle.
  • 4. Re: LDAP lookup using managed ODP.NET fails in C# application
    987532 Newbie
    Currently Being Moderated
    I can't provide my own ORA files because there is other information in the central ORA files that is successfully read and used. Yes, I could copy them and add my connection string, but this moves away from the centrally controlled ORA files (copying them will cause a problem if the central ones should change).

    I want to leave the centrally controlled ORA files as they are and, if I can't perform an LDAP lookup, just add a hostname/connection string at run-time either by hardcoding, or maybe even another ORA-file local to my application that just augments the centrally controlled ones in C:\Apps\oracle\network\admin. Not ideal, but acceptable.

    I could try querying LDAP directly in C# (ideal solution for me as connection string still obtained from the server) - this is not difficult to do (http://www.google.co.uk/search?q=c%23+query+ldap), and I have the server name, but I have no idea what other parameters to specify when constructing the DirectorySearcher object in C#.

    The ldap.ora file is in this format:
    # LDAP.ORA Configuration
    # Generated by Oracle configuration tools.
    DEFAULT_ADMIN_CONTEXT = "dc=xx,dc=mycompany,dc=com"
    DIRECTORY_SERVERS = (ldap_server1.mycompany.com:389:636,ldap_server2.mycompany.com:389:636, ...)
    DIRECTORY_SERVER_TYPE = OID
    I know this is now more of a C#/.NET issue, but my query now is, how do I map this to setting up the LDAP query in my C# code? I've asked a similar question on Stack Overflow (http://stackoverflow.com/questions/14566632), but if anyone here knows that answer, that would be fantastic.

    PS: Who is Alex who could advise on when/if LDAP will be supported by managed ODP.NET?
  • 5. Re: LDAP lookup using managed ODP.NET fails in C# application
    Tridus Journeyer
    Currently Being Moderated
    984529 wrote:
    I can't provide my own ORA files because there is other information in the central ORA files that is successfully read and used. Yes, I could copy them and add my connection string, but this moves away from the centrally controlled ORA files (copying them will cause a problem if the central ones should change).

    I want to leave the centrally controlled ORA files as they are and, if I can't perform an LDAP lookup, just add a hostname/connection string at run-time either by hardcoding, or maybe even another ORA-file local to my application that just augments the centrally controlled ones in C:\Apps\oracle\network\admin. Not ideal, but acceptable.
    I'm pretty sure you can put all the server hostname/connection into directly into a connection string, if you expand it out. I don't have an example of my own to give you, but I saw this online and it might be worth trying:

    "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=MyHost)(PORT=MyPort))(CONNECT_D‚ÄčATA=(SERVICE_NAME=MyOracleSID)));User ID=myUsername;Password=myPassword;"

    Just pull the relevant info for that connection out of tnsnames.ora and add it here, along with the usual username/password. The whole thing becomes your connection string.
    PS: Who is Alex who could advise on when/if LDAP will be supported by managed ODP.NET?
    Alex Keh, the ODP.net product manager.
  • 6. Re: LDAP lookup using managed ODP.NET fails in C# application
    987532 Newbie
    Currently Being Moderated
    Yes, I thought about just using the full connection string (which I already have from the tnsping output), but I wanted to try and get this from the LDAP lookup dynamically so that I don't hardcode the connection string into my code.

    Someone came up with an "almost-solution": http://stackoverflow.com/a/14569342/197591

    However, I'm still struggling authenticating myself on the LDAP server. I'm successfully finding the LDAP server in my C# code, but it's not accepting my domain/username and password. I assumed it would be my Windows login username/password and the domain would be that shown in Control Panel->System. However, it gives an exception saying my "account is locked" that is the same exception whatever username I enter. So, this is obviously a standard error message if it doesn't recognise the username.

    So, how do I find the domain/username/password I should use? I have some files in C:\Apps\oracle\network\admin such as krb5.conf, krb5.realms and sqlnet.ora.kerberos. Would any of these provide clues (I can't see anything obvious)?
  • 7. Re: LDAP lookup using managed ODP.NET fails in C# application
    Tridus Journeyer
    Currently Being Moderated
    It may not need authentication at all. If it does, here's some code examples on how to use it: http://stackoverflow.com/questions/11561689/using-c-sharp-to-authenticate-user-against-ldap

    I don't know anything about how your LDAP server is configured, so I can't be of much help there. :(
  • 8. Re: LDAP lookup using managed ODP.NET fails in C# application
    987532 Newbie
    Currently Being Moderated
    Thanks, that gave me a big clue. I had to specify the AuthenticationType on the C# object (DirectoryEntry) to be None or Anonymous.

    This is the final C# code that works:
    string directoryServer = "ldap_server1.mycompany.com:389";
    string defaultAdminContext = "dc=xx,dc=mycompany,dc=com";
    string oracleHostEntryPath = string.Format("LDAP://{0}/cn=OracleContext,{1}", directoryServer, defaultAdminContext);

    var directoryEntry = new DirectoryEntry(oracleHostEntryPath) {AuthenticationType = AuthenticationTypes.None};
    var directorySearcher = new DirectorySearcher(directoryEntry, "(&(objectclass=orclNetService)(cn=ABCDEFG1))", new[] { "orclnetdescstring" }, SearchScope.Subtree);

    string oracleNetDescription = Encoding.Default.GetString(des.FindOne().Properties["orclnetdescstring"][0] as byte[]);
    The true solution came when I found this article: http://www.codeproject.com/Articles/472540/Alternative-tnsping-utility

    That has a whole C# method for performing LDAP lookups and even uses the ldap.ora file directly to get the LDAP server names. Exactly what I needed!

    The only outstanding matter now is, how do I distinguish between a DataSource that is a hostname and one that is a full connection string? Because I only want to do an LDAP lookup on a hostname if the DataSource is actually a hostname.

    Thanks for all your help with this :)
  • 9. Re: LDAP lookup using managed ODP.NET fails in C# application
    Tridus Journeyer
    Currently Being Moderated
    Well, if the full connection string is a full TNS entry like I posted earlier, it'd be easy to look at the connection string and just see if it's that. There's a bunch of stuff in there that won't appear normally if it's just a hostname.

    Alternately if it's a TNS name from your existing TNS file, you could parse that file and see if it's in there.

    You could try to ping it and see if it responds.

    A crude method would be to just try to connect, and if it fails then go to LDAP and look it up.
  • 10. Re: LDAP lookup using managed ODP.NET fails in C# application
    987532 Newbie
    Currently Being Moderated
    I worked out a solution in the end, which I put here: http://stackoverflow.com/a/14653422/197591

    It's pretty much your first suggestion.

    Thanks :)
  • 11. Re: LDAP lookup using managed ODP.NET fails in C# application
    987532 Newbie
    Currently Being Moderated
    Hi Tridus, maybe you or Alex can help with another Managed ODP.NET query I have to do with SafeMapping, which seems not to be supported. I've posted the question here: NotSupportedException on OracleDataAdapter.SafeMapping on Managed ODP.NET

    Thanks!
  • 12. Re: LDAP lookup using managed ODP.NET fails in C# application
    Alex_Keh - Oracle_Product_Manager Expert
    Currently Being Moderated
    Native ODP.NET, Managed Driver support for LDAP won't be available in the first production release. We hope to provide this feature by the following production release.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points