ruby-oci8 icon indicating copy to clipboard operation
ruby-oci8 copied to clipboard

OCI8 hangs when switching to LDAP

Open arjes opened this issue 11 years ago • 14 comments

Hello,

I have previously been connecting fine with EZCONNECT through Ruby-OCI8. Unfortunately my enterprise is switching to LDAP auth only and I need to get my application working in this manner.

I can connect via sqlplus fine. "sqlplus username/[email protected]"

but when I try this via ruby:

OCI8.new 'username','password', 'DBNAME.DB.CORP.com' or OCI8.new 'username/[email protected]'

the process hangs.

I have left it running for hours and have not gotten an error.

Additionally if I remove the LDAP config file, I get an error immediately.

I am not sure how to debug this, is there a verbose mode for OCI8?

arjes avatar Apr 10 '13 17:04 arjes

Could you run the following one liner? If your script loads a ldap library before requiring oci8, it may cause unexpected behaviour by function interposition.

ruby -roci8 -e "OCI8.new('username/[email protected]').exec('select * from dual') do |row| puts row[0]; end"

What platform do you use? If you use Linux, could you post the hung process's module list and backtraces for each thread?

$ cat /proc/<PID>/maps
$ gdb `which ruby` <PID>
(gdb) info threads   # get thread id list
(gdb) thread 1    # change the context to thread 1
(gdb) bt  # get the backtrace of thread 1
(gdb) thread 2    # change the context to thread 2
(gdb) bt  # get the backtrace of thread 2
   ...

kubo avatar Apr 11 '13 12:04 kubo

No response. Can I close this issue? I know nothing about LDAP. I cannot build LDAP auth environment to check the issue.

kubo avatar Apr 19 '13 22:04 kubo

I am sorry, work had ben very busy. I will try to get you what you need on monday. On Apr 19, 2013 6:09 PM, "Kubo Takehiro" [email protected] wrote:

No response. Can I close this issue? I know nothing about LDAP. I cannot build LDAP auth environment to check the issue.

— Reply to this email directly or view it on GitHubhttps://github.com/kubo/ruby-oci8/issues/32#issuecomment-16692497 .

arjes avatar Apr 19 '13 23:04 arjes

See http://stackoverflow.com/questions/15205743/link-to-specific-oracle-instant-client-dynamic-library-on-os-x/15322554#15322554 Perhaps it is caused by same reason.

kubo avatar Apr 20 '13 03:04 kubo

kubo, I'm so sorry that this took so long. Work.... :(

Anyway your one liner did connect, so it must be a issue with the order of inclusion. I'm using bundler so I will fool around with the define order.

Thank you so much for keeping this issue open.

arjes avatar Jun 11 '13 15:06 arjes

In the interest of closure, the issue was the mysql2 gem

arjes avatar Jun 11 '13 15:06 arjes

Does anyone understand what is causing this issue exactly? I have an application that needs to connect to both an Oracle database and a PostGres database, and I keep running into this problem. It happens before the application even tries to open a PostGres connection. It seems like just having "require 'pg'" anywhere in my code can trigger it.

Once in a while I happen to stumble on a configuration that seems to avoid the problem, but then I adjust something else and it breaks again, and I can't figure out what distinguishes a working setup from a non-working one. I have an uneasy feeling that it's based on some non-deterministic factor.

EvanGranthamBrown avatar Jul 16 '15 15:07 EvanGranthamBrown

@EvanGranthamBrown What OS do you use?

If it is Linux, could you post the output of the following command or send it to [email protected]?

env LD_DEBUG=all ruby not_working_script.rb

If it is OS X, use the following command.

env DYLD_PRINT_LIBRARIES=1 DYLD_PRINT_BINDINGS=1 ruby not_working_script.rb

kubo avatar Jul 16 '15 22:07 kubo

E-mailing it, since the output was about 4K lines. My system is a Vagrant VM running CentOS (on a Windows host, if it matters).

Thanks!

EvanGranthamBrown avatar Jul 17 '15 14:07 EvanGranthamBrown

It is indeed function interposition.

     17022:     binding file /usr/lib/oracle/11.2/client64/lib/libclntsh.so.11.1 [0] to /lib64/libldap_r-2.4.so.2 [0]: normal symbol `ldap_open'

ldap_open is in both libclntsh.so.11.1 and libldap_r-2.4.so.2. Though libclntsh.so.11.1 should use ldap_open in libclntsh.so.11.1, it uses ldap_open in libldap_r-2.4.so.2. If require 'oci8' is put before require 'pg', the line will be changed as follows:

     17022:     binding file /usr/lib/oracle/11.2/client64/lib/libclntsh.so.11.1 [0] to /usr/lib/oracle/11.2/client64/lib/libclntsh.so.11.1 [0]: normal symbol `ldap_open'

It happens before the application even tries to open a PostGres connection.

The issue doesn't depend on the order of function calls. It depends on the order of library loading, which is triggered by require 'xxx'.

It seems like just having "require 'pg'" anywhere in my code can trigger it.

Does it happens even though require 'oci8' is before require 'pg'?

Once in a while I happen to stumble on a configuration that seems to avoid the problem, but then I adjust something else and it breaks again, and I can't figure out what distinguishes a working setup from a non-working one

Could you run your scripts with LD_DEBUG=bindings and LD_DEBUG_OUTPUT=ld_debug.log and check binding of ldap_open? The log is outputtted to ld_debug.log.<PID>

kubo avatar Jul 20 '15 01:07 kubo

Accoding to http://pgxn.org/dist/oracle_fdw/ the Oracle client shared library comes with its own LDAP client implementation conforming to RFC 1823, so these functions have the same names as OpenLDAP's. This will lead to a name collision. This also could be issue with the postgres client, which uses libldap. I would try to compile libpg without ldap.

tomasjura avatar Jan 01 '16 22:01 tomasjura

I'm also encountering this issue, I'm using both oci8 and activeldap, using an ActiveLdap gives a "NoMemoryError: failed to allocate memory" strace shows mmap(NULL, 7809846622694674432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)

lolorc avatar Sep 22 '16 14:09 lolorc

compiling ruby-oci8 with #define DLOPEN_FLAG (RTLD_NOW|RTLD_LOCAL) and requiring "oci8" first does the trick. Thanks kubo, would it be possible to have a fix in the next release ?

lolorc avatar Sep 22 '16 14:09 lolorc

I made a document about LDAP auth. http://www.rubydoc.info/github/kubo/ruby-oci8/file/docs/ldap-auth-and-function-interposition.md I'll close this issue after I add solution using DLOPEN_FLAGS. As far as I checked (RTLD_NOW|RTLD_LOCAL) does the trick only on limited platforms.

kubo avatar Jan 09 '17 03:01 kubo