ruby-oci8 2.2.3 → 2.2.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ChangeLog +427 -0
- data/NEWS +335 -42
- data/README.md +20 -9
- data/dist-files +9 -3
- data/docs/bind-array-to-in_cond.md +2 -2
- data/docs/conflicts-local-connections-and-processes.md +7 -4
- data/docs/hanging-after-inactivity.md +63 -0
- data/docs/install-binary-package.md +15 -11
- data/docs/install-full-client.md +18 -21
- data/docs/install-instant-client.md +45 -27
- data/docs/install-on-osx.md +31 -120
- data/docs/ldap-auth-and-function-interposition.md +123 -0
- data/docs/number-type-mapping.md +79 -0
- data/docs/platform-specific-issues.md +17 -50
- data/docs/report-installation-issue.md +3 -0
- data/docs/timeout-parameters.md +3 -0
- data/ext/oci8/apiwrap.c.tmpl +2 -5
- data/ext/oci8/apiwrap.rb +6 -1
- data/ext/oci8/apiwrap.yml +34 -22
- data/ext/oci8/attr.c +4 -2
- data/ext/oci8/bind.c +366 -6
- data/ext/oci8/connection_pool.c +3 -3
- data/ext/oci8/encoding.c +5 -5
- data/ext/oci8/env.c +8 -2
- data/ext/oci8/error.c +24 -16
- data/ext/oci8/extconf.rb +8 -4
- data/ext/oci8/hook_funcs.c +274 -61
- data/ext/oci8/lob.c +31 -75
- data/ext/oci8/metadata.c +2 -2
- data/ext/oci8/object.c +72 -27
- data/ext/oci8/oci8.c +45 -132
- data/ext/oci8/oci8.h +32 -88
- data/ext/oci8/oci8lib.c +178 -38
- data/ext/oci8/ocihandle.c +37 -37
- data/ext/oci8/ocinumber.c +23 -18
- data/ext/oci8/oraconf.rb +158 -339
- data/ext/oci8/oradate.c +19 -19
- data/ext/oci8/plthook.h +10 -0
- data/ext/oci8/plthook_elf.c +433 -268
- data/ext/oci8/plthook_osx.c +40 -9
- data/ext/oci8/plthook_win32.c +9 -0
- data/ext/oci8/stmt.c +52 -17
- data/ext/oci8/win32.c +4 -22
- data/lib/oci8/bindtype.rb +1 -15
- data/lib/oci8/check_load_error.rb +57 -10
- data/lib/oci8/cursor.rb +57 -25
- data/lib/oci8/metadata.rb +9 -1
- data/lib/oci8/object.rb +10 -0
- data/lib/oci8/oci8.rb +33 -28
- data/lib/oci8/oracle_version.rb +11 -1
- data/lib/oci8/properties.rb +22 -0
- data/lib/oci8/version.rb +1 -1
- data/lib/oci8.rb +48 -4
- data/lib/ruby-oci8.rb +0 -3
- data/pre-distclean.rb +1 -3
- data/ruby-oci8.gemspec +3 -8
- data/setup.rb +11 -2
- data/test/README.md +37 -0
- data/test/config.rb +1 -1
- data/test/setup_test_object.sql +21 -13
- data/test/setup_test_package.sql +59 -0
- data/test/test_all.rb +2 -0
- data/test/test_bind_boolean.rb +99 -0
- data/test/test_bind_integer.rb +47 -0
- data/test/test_break.rb +11 -9
- data/test/test_clob.rb +4 -16
- data/test/test_connstr.rb +29 -13
- data/test/test_datetime.rb +8 -3
- data/test/test_object.rb +27 -9
- data/test/test_oci8.rb +170 -46
- data/test/test_oranumber.rb +12 -6
- data/test/test_package_type.rb +15 -3
- data/test/test_properties.rb +17 -0
- metadata +40 -54
- data/docs/osx-install-dev-tools.png +0 -0
- data/test/README +0 -42
@@ -0,0 +1,63 @@
|
|
1
|
+
# @title Hanging After a Long Period of Inactivity
|
2
|
+
|
3
|
+
Hanging After a Long Period of Inactivity
|
4
|
+
=========================================
|
5
|
+
|
6
|
+
When a database connection hangs after a long period of inactivity,
|
7
|
+
this document may help you.
|
8
|
+
|
9
|
+
When a firewall or a NAT proxy resides between Oracle database server
|
10
|
+
and client, it sometimes drops inactive connections as dead ones. If a
|
11
|
+
client connects to an Oracle server and tries to use the connection
|
12
|
+
after a long sleep (> 1 hour), the client may hang in an effort to use the
|
13
|
+
dropped connection. This issue will be solved by setting TCP keepalive
|
14
|
+
packets whose keepalive time parameter is smaller than the inactive
|
15
|
+
connection timeout.
|
16
|
+
|
17
|
+
TCP keepalive is enabled by [(ENABLE=broken)][] in a connect
|
18
|
+
descriptor. If you use easy connect naming such as `//hostname/service_name`,
|
19
|
+
ruby-oci8 sets the parameter on behalf of you when the `tcp_keepalive`
|
20
|
+
property is set. (This is available since ruby-oci8 2.2.4.)
|
21
|
+
|
22
|
+
OCI8.properties[:tcp_keepalive] = true
|
23
|
+
conn = OCI8.new(username, password, '//hostname/service_name')
|
24
|
+
|
25
|
+
This is equivalent to the following:
|
26
|
+
|
27
|
+
connect_descriptor = "(DESCRIPTION=(ENABLE=broken)(ADDRESS=(PROTOCOL=tcp)(HOST=hostname)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=service_name)))"
|
28
|
+
conn = OCI8.new(username, password, connect_descriptor)
|
29
|
+
|
30
|
+
The default TCP keepalive time is two hours, which may be larger
|
31
|
+
than the inactive connection timeout. The default
|
32
|
+
value in the system is configurable via [procfs and sysctl on Linux][]
|
33
|
+
or [registry parameters on Windows][]. If you have no privilege to
|
34
|
+
customize the system, you can change per-connection keepalive time
|
35
|
+
by the `tcp_keepalive_time` property.
|
36
|
+
|
37
|
+
OCI8.properties[:tcp_keepalive_time] = 600 # 10 minutes
|
38
|
+
|
39
|
+
It is supported on the following platforms since ruby-oci8 2.2.4.
|
40
|
+
|
41
|
+
* Linux i386 and x86_64
|
42
|
+
* macOS
|
43
|
+
* Windows x86 and x64
|
44
|
+
* Solaris x86_64
|
45
|
+
|
46
|
+
When it is set on unsupported platforms, you get `NotImplementedError`.
|
47
|
+
|
48
|
+
This feature is implemented with hackish way. When
|
49
|
+
`tcp_keepalive_time` is set, Oracle client library's
|
50
|
+
procedure linkage table is modified to intercept [setsockopt][] system
|
51
|
+
call. When Oracle client library issues the system call which enables
|
52
|
+
TCP keepalive, [ruby-oci8 changes][] the per-connection TCP keepalive time
|
53
|
+
immediately.
|
54
|
+
|
55
|
+
I hope that Oracle adds a new OCI handle attribute to support this
|
56
|
+
feature natively in the future.
|
57
|
+
|
58
|
+
[(ENABLE=broken)]: https://docs.oracle.com/database/121/NETRF/tnsnames.htm#CHDCDGCE
|
59
|
+
[procfs and sysctl on Linux]: http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html
|
60
|
+
[registry parameters on Windows]: https://blogs.technet.microsoft.com/nettracer/2010/06/03/things-that-you-may-want-to-know-about-tcp-keepalives/
|
61
|
+
[plthook]: https://github.com/kubo/plthook
|
62
|
+
[setsockopt]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html
|
63
|
+
[ruby-oci8 changes]: https://github.com/kubo/ruby-oci8/blob/ruby-oci8-2.2.4/ext/oci8/hook_funcs.c#L302-L318
|
@@ -1,24 +1,28 @@
|
|
1
1
|
# @title Install Binary Package
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
Install Binary Package
|
4
|
+
======================
|
5
5
|
|
6
|
-
|
6
|
+
Windows
|
7
|
+
-------
|
7
8
|
|
8
|
-
|
9
|
+
You need to install Oracle client in advance.
|
10
|
+
If you don't have installed Oracle client, install {file:docs/install-instant-client.md#Install_Oracle_Instant_Client_Packages instant client}. Only the Basic or Basic Lite package is needed to use ruby-oci8.
|
11
|
+
However it is better to install SQL*Plus also because it is usable to check whether
|
12
|
+
a problem is in Oracle setting or in ruby-oci8.
|
13
|
+
|
14
|
+
Run the following command to install ruby-oci8.
|
9
15
|
|
10
|
-
|
11
|
-
=============================
|
16
|
+
gem install ruby-oci8
|
12
17
|
|
13
|
-
|
18
|
+
If you uses mswin32 ruby, use the following command instead.
|
14
19
|
|
15
20
|
gem install --platform x86-mingw32 ruby-oci8
|
16
|
-
|
17
|
-
|
18
|
-
If it doesn't work, see {file:docs/install-instant-client.md} or {file:docs/install-full-client.md}.
|
21
|
+
or
|
22
|
+
gem install --platform x64-mingw32 ruby-oci8
|
19
23
|
|
20
24
|
Other platforms
|
21
|
-
|
25
|
+
---------------
|
22
26
|
|
23
27
|
We doesn't make binary gems for other platforms.
|
24
28
|
If you need to distribute a binary gem, compile ruby-oci8 and run the following command.
|
data/docs/install-full-client.md
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# @title Install for Oracle Full Client
|
2
2
|
|
3
|
+
Install for Oracle Full Client
|
4
|
+
==============================
|
5
|
+
|
3
6
|
Introduction
|
4
|
-
|
7
|
+
------------
|
5
8
|
|
6
9
|
This page explains the way to install ruby-oci8 for Oracle Full Client
|
7
10
|
installations.
|
@@ -11,18 +14,16 @@ For Windows, look at {file:docs/install-binary-package.md} unless you
|
|
11
14
|
have a special need to compile ruby-oci8 by yourself.
|
12
15
|
|
13
16
|
Check the environment
|
14
|
-
|
17
|
+
---------------------
|
15
18
|
|
16
|
-
Oracle installation
|
17
|
-
-------------------
|
19
|
+
### Oracle installation
|
18
20
|
|
19
21
|
Run the following command and confirm it works fine. If it doesn't
|
20
22
|
work well, you need to ask to your database administrator.
|
21
23
|
|
22
24
|
sqlplus USERNAME/PASSWORD
|
23
25
|
|
24
|
-
ruby installation
|
25
|
-
-----------------
|
26
|
+
### ruby installation
|
26
27
|
|
27
28
|
Run the following command. If it ends with "can't find header files
|
28
29
|
for ruby" or "ruby: no such file to load -- mkmf (LoadError)", you need
|
@@ -30,8 +31,7 @@ to install ruby-devel(redhat) or ruby-dev(debian/ubuntu).
|
|
30
31
|
|
31
32
|
ruby -r mkmf -e ""
|
32
33
|
|
33
|
-
development tools
|
34
|
-
-----------------
|
34
|
+
### development tools
|
35
35
|
|
36
36
|
You need a C compiler and development tools such as make or nmake.
|
37
37
|
Note that they must be same with ones used to compile the ruby.
|
@@ -39,15 +39,14 @@ For example, you need Oracle Solaris Studio, not gcc, for ruby
|
|
39
39
|
compiled by Oracle Solaris Studio.
|
40
40
|
|
41
41
|
Installation
|
42
|
-
|
42
|
+
------------
|
43
43
|
|
44
44
|
If you get a problem in the following steps, look at {file:docs/platform-specific-issues.md}
|
45
45
|
and {file:docs/report-installation-issue.md}.
|
46
46
|
|
47
|
-
Set the library search path
|
48
|
-
---------------------------
|
47
|
+
### Set the library search path
|
49
48
|
|
50
|
-
|
49
|
+
#### UNIX
|
51
50
|
|
52
51
|
Set the library search path, whose name depends on the OS, to point to
|
53
52
|
$ORACLE\_HOME/lib. If the database is 64-bit and the ruby is 32-bit,
|
@@ -74,27 +73,25 @@ Do not forget to export the variable as follows:
|
|
74
73
|
$ LD_LIBRARY_PATH=$ORACLE_HOME/lib
|
75
74
|
$ export LD_LIBRARY_PATH
|
76
75
|
|
77
|
-
|
76
|
+
#### Windows(mswin32, mingw32, cygwin)
|
78
77
|
|
79
78
|
If sqlplus runs correctly, library search path has no problem.
|
80
79
|
|
81
|
-
gem package
|
82
|
-
-----------
|
80
|
+
### gem package
|
83
81
|
|
84
82
|
Run the following command.
|
85
83
|
|
86
84
|
gem install ruby-oci8
|
87
85
|
|
88
|
-
tar.gz package
|
89
|
-
--------------
|
86
|
+
### tar.gz package
|
90
87
|
|
91
|
-
|
88
|
+
#### Download the source code
|
92
89
|
|
93
90
|
Download the latest tar.gz package from [download page][].
|
94
91
|
|
95
|
-
|
92
|
+
#### Run make and install
|
96
93
|
|
97
|
-
|
94
|
+
##### UNIX or Windows(mingw32, cygwin)
|
98
95
|
|
99
96
|
gzip -dc ruby-oci8-VERSION.tar.gz | tar xvf -
|
100
97
|
cd ruby-oci8-VERSION
|
@@ -104,7 +101,7 @@ Download the latest tar.gz package from [download page][].
|
|
104
101
|
note: If you use '`sudo`', use it only when running '`make install`'.
|
105
102
|
'`sudo`' doesn't pass library search path to the executing command for security reasons.
|
106
103
|
|
107
|
-
|
104
|
+
##### Windows(mswin32)
|
108
105
|
|
109
106
|
gzip -dc ruby-oci8-VERSION.tar.gz | tar xvf -
|
110
107
|
cd ruby-oci8-VERSION
|
@@ -1,7 +1,10 @@
|
|
1
1
|
# @title Install for Oracle Instant Client
|
2
2
|
|
3
|
+
Install for Oracle Instant Client
|
4
|
+
=================================
|
5
|
+
|
3
6
|
Introduction
|
4
|
-
|
7
|
+
------------
|
5
8
|
|
6
9
|
This page explains the way to install ruby-oci8 for Oracle Instant Client.
|
7
10
|
|
@@ -13,10 +16,10 @@ have a special need to compile ruby-oci8 by yourself.
|
|
13
16
|
Look at {file:docs/install-on-osx.md} for OS X.
|
14
17
|
|
15
18
|
Install Oracle Instant Client Packages
|
16
|
-
|
19
|
+
--------------------------------------
|
20
|
+
|
21
|
+
### Download Instant Client Packages
|
17
22
|
|
18
|
-
Donwload Instant Client Packages
|
19
|
-
--------------------------------
|
20
23
|
Download the following packages from [Oracle Technology Network](http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html).
|
21
24
|
|
22
25
|
* Instant Client Package - Basic or Basic Lite
|
@@ -25,8 +28,7 @@ Download the following packages from [Oracle Technology Network](http://www.orac
|
|
25
28
|
|
26
29
|
Note: use 32-bit packages for 32-bit ruby even though the OS is 64-bit.
|
27
30
|
|
28
|
-
UNIX zip packages
|
29
|
-
-----------------
|
31
|
+
### UNIX zip packages
|
30
32
|
|
31
33
|
Unzip the packages as follows:
|
32
34
|
|
@@ -79,8 +81,7 @@ Though many instant client pages indicate that the environment varialbe
|
|
79
81
|
configuration files such as `tnsnames.ora` and `sqlnet.ora` are in
|
80
82
|
`$ORACLE_HOME/network/admin/`.
|
81
83
|
|
82
|
-
Linux rpm packages
|
83
|
-
------------------
|
84
|
+
### Linux rpm packages
|
84
85
|
|
85
86
|
Install the downloaded packages as follows:
|
86
87
|
|
@@ -95,24 +96,44 @@ For example:
|
|
95
96
|
$ LD_LIBRARY_PATH=/usr/lib/oracle/12.1/client/lib
|
96
97
|
$ export LD_LIBRARY_PATH
|
97
98
|
|
98
|
-
Windows
|
99
|
-
|
99
|
+
### Windows
|
100
|
+
|
101
|
+
Unzip the packages and set `PATH` to point to the directory where `OCI.DLL` is installed.
|
102
|
+
|
103
|
+
If `require "ruby-oci8"` raises a load error such as "OCI.DLL: 126(The
|
104
|
+
specified module could not be found. )", either `OCI.DLL` or a DLL depended
|
105
|
+
by `OCI.DLL` could not be found in `PATH`.
|
106
|
+
|
107
|
+
If `OCI.DLL` is surely in `PATH`, the missing module is a Visual C++ runtime
|
108
|
+
library in most cases. You need to install "Microsoft Visual C++ Redistributable
|
109
|
+
Package" or copy a runtime library to the directory where `ruby.exe` resides.
|
110
|
+
|
111
|
+
| Oracle Version | Package | Runtime Library|
|
112
|
+
|---|---|---|
|
113
|
+
| 18.3 | [Microsoft Visual C++ 2013 Redistributable Package][2013] | MSVCR120.DLL |
|
114
|
+
| 12.2.0.x | [Microsoft Visual C++ 2013 Redistributable Package][2013] | MSVCR120.DLL |
|
115
|
+
| 12.1.0.x | [Microsoft Visual C++ 2010 Redistributable Package][2010] | MSVCR100.DLL |
|
116
|
+
| 11.2.0.x | Microsoft Visual C++ 2005 SP1 Redistributable Package ([x86][2005SP1_x86], [x64][2005SP1_x64]) | MSVCR80.DLL(The file version must be 8.0.50727.762.) |
|
117
|
+
| 11.1.0.x | [No separate redistributable package][2003] | MSVCR71.DLL |
|
118
|
+
| 10.2.0.x | [No separate redistributable package][2003] | MSVCR71.DLL |
|
100
119
|
|
101
|
-
|
120
|
+
[2013]: https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
|
121
|
+
[2010]: http://www.microsoft.com/en-us/download/details.aspx?id=26999
|
122
|
+
[2005SP1_x86]: https://www.microsoft.com/en-us/download/details.aspx?id=5638
|
123
|
+
[2005SP1_x64]: https://www.microsoft.com/en-us/download/details.aspx?id=18471
|
124
|
+
[2003]: http://stackoverflow.com/questions/1596167/where-to-download-microsoft-visual-c-2003-redistributable#6132093
|
102
125
|
|
103
126
|
Check the environment
|
104
|
-
|
127
|
+
---------------------
|
105
128
|
|
106
|
-
Oracle installation
|
107
|
-
-------------------
|
129
|
+
### Oracle installation
|
108
130
|
|
109
131
|
Run the following command and confirm it works fine. If it doesn't
|
110
132
|
work well, check `LD_LIBRARY_PATH` or PATH.
|
111
133
|
|
112
134
|
sqlplus USERNAME/PASSWORD
|
113
135
|
|
114
|
-
ruby installation
|
115
|
-
-----------------
|
136
|
+
### ruby installation
|
116
137
|
|
117
138
|
Run the following command. If it ends with "can't find header files
|
118
139
|
for ruby" or "ruby: no such file to load -- mkmf (LoadError)", you need
|
@@ -120,8 +141,7 @@ to install ruby-devel(redhat) or ruby-dev(debian/ubuntu).
|
|
120
141
|
|
121
142
|
ruby -r mkmf -e ""
|
122
143
|
|
123
|
-
development tools
|
124
|
-
-----------------
|
144
|
+
### development tools
|
125
145
|
|
126
146
|
You need a C compiler and development tools such as make or nmake.
|
127
147
|
Note that they must be same with ones used to compile the ruby.
|
@@ -129,13 +149,12 @@ For example, you need Oracle Solaris Studio, not gcc, for ruby
|
|
129
149
|
compiled by Oracle Solaris Studio.
|
130
150
|
|
131
151
|
Installation
|
132
|
-
|
152
|
+
------------
|
133
153
|
|
134
154
|
If you get a problem in the following steps, look at {file:docs/platform-specific-issues.md}
|
135
155
|
and {file:docs/report-installation-issue.md}.
|
136
156
|
|
137
|
-
gem package
|
138
|
-
-----------
|
157
|
+
### gem package
|
139
158
|
|
140
159
|
Run the following command.
|
141
160
|
|
@@ -144,19 +163,18 @@ Run the following command.
|
|
144
163
|
If you get a problem, look at {file:docs/platform-specific-issues.md}
|
145
164
|
and {file:docs/report-installation-issue.md}.
|
146
165
|
|
147
|
-
tar.gz package
|
148
|
-
--------------
|
166
|
+
### tar.gz package
|
149
167
|
|
150
|
-
|
168
|
+
#### Download the source code
|
151
169
|
|
152
170
|
Download the latest tar.gz package from [download page][].
|
153
171
|
|
154
172
|
Note: if you are using Windows and you have no special need to compile
|
155
173
|
it by yourself, look at {file:docs/install-binary-packge.md}.
|
156
174
|
|
157
|
-
|
175
|
+
#### Run make and install
|
158
176
|
|
159
|
-
|
177
|
+
##### UNIX or Windows(mingw32, cygwin)
|
160
178
|
|
161
179
|
gzip -dc ruby-oci8-VERSION.tar.gz | tar xvf -
|
162
180
|
cd ruby-oci8-VERSION
|
@@ -166,7 +184,7 @@ it by yourself, look at {file:docs/install-binary-packge.md}.
|
|
166
184
|
note: If you use '`sudo`', use it only when running '`make install`'.
|
167
185
|
'`sudo`' doesn't pass library search path to the executing command for security reasons.
|
168
186
|
|
169
|
-
|
187
|
+
##### Windows(mswin32)
|
170
188
|
|
171
189
|
gzip -dc ruby-oci8-VERSION.tar.gz | tar xvf -
|
172
190
|
cd ruby-oci8-VERSION
|
data/docs/install-on-osx.md
CHANGED
@@ -1,135 +1,46 @@
|
|
1
|
-
# @title Install ruby-oci8 on
|
1
|
+
# @title Install ruby-oci8 on macOS
|
2
2
|
|
3
|
-
|
3
|
+
Install ruby-oci8 on macOS
|
4
|
+
=========================
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
**Note: Ruby-oci8 doesn't run on Apple Silicon because Oracle instant client
|
7
|
+
for Apple Silicon has not been released yet.**
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
Prerequisite
|
10
|
+
------------
|
10
11
|
|
11
|
-
|
12
|
-
(The latter includes the former.)
|
13
|
-
|
14
|
-
Run `"cc --version"` in a terminal to check whether they are installed.
|
15
|
-
|
16
|
-
If the cc version is printed, the tools are installed.
|
17
|
-
|
18
|
-
If the follwoing dialog is displayed, click its Install button to
|
19
|
-
install the tools.
|
20
|
-
You have no need to install the Xcode to compile ruby-oci8.
|
21
|
-
It requires command line tools, not an IDE such as the Xcode.
|
22
|
-
|
23
|
-
![dialog](osx-install-dev-tools.png)
|
24
|
-
|
25
|
-
If `"Agreeing to the Xcode/iOS license requires admin privileges,
|
26
|
-
please re-run as root via sudo."` is printed, you need to run
|
27
|
-
`"sudo cc --version"`, enter your password, look at the license
|
28
|
-
and type `"agree"`.
|
12
|
+
* Command line tools for Xcode or Xcode (by executing `xcode-select --install`) or [Xcode]
|
29
13
|
|
30
14
|
Install Oracle Instant Client Packages
|
31
|
-
|
32
|
-
|
33
|
-
Download Oracle Instant Client Packages
|
34
|
-
--------------------------------
|
35
|
-
|
36
|
-
Download the following packages from [Oracle Technology Network][]
|
37
|
-
|
38
|
-
* Instant Client Package - Basic (`instantclient-basic-macos.x64-12.1.0.2.0.zip`) or Basic Lite (`instantclient-basiclite-macos.x64-12.1.0.2.0.zip`)
|
39
|
-
* Instant Client Package - SDK (`instantclient-sdk-macos.x64-12.1.0.2.0.zip`)
|
40
|
-
* Instant Client Package - SQL*Plus (`instantclient-sdk-macos.x64-12.1.0.2.0.zip`) (optionally)
|
41
|
-
|
42
|
-
Install Oracle Instant Client Packages via Homebrew
|
43
|
-
---------------------------------------------------
|
44
|
-
|
45
|
-
To install `Oracle Instant Client Basic` via [Homebrew][]
|
46
|
-
|
47
|
-
* Copy downloaded zip files to `/Library/Caches/Homebrew`
|
48
|
-
(if the environment variable `HOMEBREW_CACHE`
|
49
|
-
is not set and `$HOME/Library/Caches/Homebrew` doesn't exist.)
|
50
|
-
|
51
|
-
* Run the followining commands:
|
52
|
-
|
53
|
-
brew tap InstantClientTap/instantclient
|
54
|
-
brew install instantclient-basic
|
55
|
-
brew install instantclient-sdk
|
56
|
-
brew install instantclient-sqlplus # (optionally)
|
57
|
-
|
58
|
-
* Set the environment variable `OCI_DIR` while performing the following installation steps
|
59
|
-
if Homebrew is installed outside `/usr/local`.
|
60
|
-
|
61
|
-
export OCI_DIR=$(brew --prefix)/lib
|
62
|
-
|
63
|
-
To install `Oracle Instant Client Basic Lite` via [Homebrew][]
|
64
|
-
|
65
|
-
* Copy downloaded zip files to `/Library/Caches/Homebrew`
|
66
|
-
(if the environment variable `HOMEBREW_CACHE`
|
67
|
-
is not set and `$HOME/Library/Caches/Homebrew` doesn't exist.)
|
68
|
-
|
69
|
-
* Run the followining commands:
|
70
|
-
|
71
|
-
brew tap InstantClientTap/instantclient
|
72
|
-
brew install instantclient-basiclite
|
73
|
-
brew install instantclient-sdk
|
74
|
-
brew install instantclient-sqlplus --with-basiclite # (optionally)
|
75
|
-
|
76
|
-
* Set the environment variable `OCI_DIR` while performing the following installation steps
|
77
|
-
if Homebrew is installed outside `/usr/local`.
|
78
|
-
|
79
|
-
export OCI_DIR=$(brew --prefix)/lib
|
80
|
-
|
81
|
-
Install Oracle Instant Client Manually
|
82
|
-
---------------------
|
83
|
-
|
84
|
-
If you don't use [Homebrew][], do the following:
|
85
|
-
|
86
|
-
Unzip the packages as follows:
|
87
|
-
|
88
|
-
mkdir -p /opt/oracle
|
89
|
-
cd /opt/oracle
|
90
|
-
|
91
|
-
Copy downloaded files to /opt/oracle before running the following commands.
|
92
|
-
|
93
|
-
unzip instantclient-basic-macos.x64-12.1.0.2.0.zip
|
94
|
-
unzip instantclient-sdk-macos.x64-12.1.0.2.0.zip
|
95
|
-
unzip instantclient-sqlplus-macos.x64-12.1.0.2.0.zip
|
96
|
-
|
97
|
-
Make a symbolic link to link the library.
|
98
|
-
|
99
|
-
cd /opt/oracle/instantclient_12_1
|
100
|
-
ln -s libclntsh.dylib.12.1 libclntsh.dylib
|
101
|
-
|
102
|
-
Set the environment variable OCI_DIR while performing the following installation steps.
|
103
|
-
|
104
|
-
export OCI_DIR=/opt/oracle/instantclient_12_1
|
105
|
-
|
106
|
-
Installation
|
107
|
-
============
|
108
|
-
|
109
|
-
If you get a problem in the following steps, look at {file:docs/report-installation-issue.md}.
|
110
|
-
|
111
|
-
gem package
|
112
|
-
-----------
|
15
|
+
--------------------------------------
|
113
16
|
|
114
|
-
|
17
|
+
If you have installed [Homebrew], use the following command:
|
115
18
|
|
116
|
-
|
19
|
+
```shell
|
20
|
+
$ brew tap InstantClientTap/instantclient
|
21
|
+
$ brew install instantclient-basic # or instantclient-basiclite
|
22
|
+
$ brew install instantclient-sdk
|
23
|
+
$ brew install instantclient-sqlplus # (optionally)
|
24
|
+
```
|
117
25
|
|
118
|
-
|
119
|
-
|
26
|
+
Otherwise, look at this [page][OTN] and set the environment variable
|
27
|
+
`OCI_DIR` to point the the directory where instant client is installed.
|
28
|
+
Ruby-oci8 installation script checks the directory.
|
120
29
|
|
121
|
-
|
30
|
+
```shell
|
31
|
+
export OCI_DIR=$HOME/Downloads/instantclient_19_8 # for example
|
32
|
+
```
|
122
33
|
|
123
|
-
|
34
|
+
Install ruby-oci8
|
35
|
+
-----------------
|
124
36
|
|
125
|
-
|
37
|
+
Note that `/usr/bin/ruby` isn't available. You need to use [`rbenv`] or so.
|
126
38
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
make install
|
39
|
+
```shell
|
40
|
+
$ gem install ruby-oci8
|
41
|
+
```
|
131
42
|
|
132
|
-
[download page]: https://bintray.com/kubo/generic/ruby-oci8
|
133
43
|
[Homebrew]: http://brew.sh/
|
134
|
-
[
|
135
|
-
[
|
44
|
+
[OTN]: https://www.oracle.com/database/technologies/instant-client/macos-intel-x86-downloads.html#ic_osx_inst
|
45
|
+
[Xcode]: https://apps.apple.com/us/app/xcode/id497799835
|
46
|
+
[`rbenv`]: https://github.com/rbenv/rbenv
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# @title LDAP Authentication and Function Interposition
|
2
|
+
|
3
|
+
LDAP Authentication and Function Interposition
|
4
|
+
==============================================
|
5
|
+
|
6
|
+
Problems
|
7
|
+
--------
|
8
|
+
|
9
|
+
The following code may trigger segmentation faults or unexpected behaviours.
|
10
|
+
|
11
|
+
require 'pg' # or any modules using LDAP such as ActiveLdap
|
12
|
+
require 'oci8'
|
13
|
+
|
14
|
+
conn = OCI8.new('username/password@dbname.example.com')
|
15
|
+
...
|
16
|
+
|
17
|
+
It happens when all the following conditions are satisfied.
|
18
|
+
|
19
|
+
* The platform is Unix
|
20
|
+
* The PostgreSQL client library, which `pg` depends, was compiled with LDAP support.
|
21
|
+
* LDAP authentication is used to connect to an Oracle server.
|
22
|
+
|
23
|
+
It is caused by function interposition as follows:
|
24
|
+
|
25
|
+
* The ruby process loads `pq` and its depending libraries such as
|
26
|
+
`libpq.so`(PostgreSQL client library) and `libldap_r.so`(LDAP library).
|
27
|
+
* Then it loads `oci8` and its depending libraries such as
|
28
|
+
`libclntsh.so`(Oracle client library).
|
29
|
+
* When LDAP authentication is used, `libclntsh.so` tries to use
|
30
|
+
LDAP functions in the library.
|
31
|
+
* However it uses LDAP functions in `libldap_r.so` because the function
|
32
|
+
in the firstly loaded library is used when more than one library exports
|
33
|
+
functions whose names are same.
|
34
|
+
* It triggers segmentation faults or unexpected behaviours because
|
35
|
+
implementations of LDAP functions are different even though their names
|
36
|
+
are same.
|
37
|
+
|
38
|
+
The reverse may cause same results by the following code.
|
39
|
+
|
40
|
+
require 'oci8'
|
41
|
+
require 'pg'
|
42
|
+
|
43
|
+
... connect to PostgreSQL using LDAP ...
|
44
|
+
|
45
|
+
### Note for macOS
|
46
|
+
|
47
|
+
Libraries in two-level namespaces are free from function interposition on macOS.
|
48
|
+
See the second paragraph of [this document][mach-o]. If `TWOLEVEL` is
|
49
|
+
found in the output of `otool -hV /path/to/library`, it is in a
|
50
|
+
two-level namespace. Otherwise it is in a single-level (flat) namespace.
|
51
|
+
|
52
|
+
Oracle client library (`libclntsh.dylib.12.1`) is in a flat namespace.
|
53
|
+
It suffers from function interposition.
|
54
|
+
|
55
|
+
$ otool -hV libclntsh.dylib.12.1
|
56
|
+
Mach header
|
57
|
+
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
58
|
+
MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 19 2360 DYLDLINK NO_REEXPORTED_DYLIBS MH_HAS_TLV_DESCRIPTORS
|
59
|
+
|
60
|
+
PostgreSQL client library (`libpq.5.dylib`) installed by [brew][] depends on an OS-supplied LDAP library.
|
61
|
+
|
62
|
+
$ otool -L libpq.5.dylib
|
63
|
+
libpq.5.dylib:
|
64
|
+
/usr/local/opt/postgresql/lib/libpq.5.dylib (compatibility version 5.0.0, current version 5.9.0)
|
65
|
+
/usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
|
66
|
+
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
|
67
|
+
/System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos (compatibility version 5.0.0, current version 6.0.0)
|
68
|
+
/System/Library/Frameworks/LDAP.framework/Versions/A/LDAP (compatibility version 1.0.0, current version 2.4.0)
|
69
|
+
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.0.0)
|
70
|
+
|
71
|
+
The OS-supplied LDAP library is in a two-level namespace.
|
72
|
+
|
73
|
+
$ otool -hV /System/Library/Frameworks/LDAP.framework/Versions/A/LDAP
|
74
|
+
Mach header
|
75
|
+
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
|
76
|
+
MH_MAGIC_64 X86_64 ALL 0x00 DYLIB 22 2528 NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS APP_EXTENSION_SAFE
|
77
|
+
|
78
|
+
As a result, the PostgreSQL client library is free from function interposition.
|
79
|
+
|
80
|
+
Solution 1
|
81
|
+
----------
|
82
|
+
|
83
|
+
If you don't connect to PostgreSQL using LDAP, use the following code.
|
84
|
+
|
85
|
+
require 'oci8' # This must be before "require 'pg'".
|
86
|
+
require 'pg'
|
87
|
+
|
88
|
+
conn = OCI8.new('username/password@dbname.example.com')
|
89
|
+
...
|
90
|
+
... connect to a PostgreSQL server ...
|
91
|
+
|
92
|
+
Oracle client library uses LDAP functions in `libclntsh.so` because `libclntsh.so`
|
93
|
+
is loaded before `libldap_r.so`.
|
94
|
+
|
95
|
+
Don't connect to PostgreSQL using LDAP because `libpq.so` tries to use
|
96
|
+
LDAP functions in `libldap_r.so` but faultily uses functions in `libclntsh.so`.
|
97
|
+
|
98
|
+
Note for macOS: This fixes all function interposition issues if the LDAP library
|
99
|
+
in a two-level namespace.
|
100
|
+
|
101
|
+
Solution 2
|
102
|
+
----------
|
103
|
+
|
104
|
+
If LDAP is used to connect to both Oracle and PostgreSQL and the platform
|
105
|
+
is Linux or macOS, use ruby-oci8 2.2.4 or later and use the following code.
|
106
|
+
|
107
|
+
require 'pg'
|
108
|
+
require 'oci8' # This must be after "require 'pg'".
|
109
|
+
|
110
|
+
conn = OCI8.new('username/password@dbname.example.com')
|
111
|
+
...
|
112
|
+
... connect to a PostgreSQL server using LDAP ...
|
113
|
+
|
114
|
+
PostgreSQL client library uses LDAP functions in `libldap_r.so` because `libldap_r.so`
|
115
|
+
is loaded before `libclntsh.so`.
|
116
|
+
|
117
|
+
Oracle client library uses LDAP functions in `libclntsh.so` because ruby-oci8
|
118
|
+
forcedly modifies PLT (Procedure Linkage Table) entries to point to
|
119
|
+
functions in `libclntsh.so` if they point to functions in other libraries.
|
120
|
+
(PLT is equivalent to IAT (Import Address Table) on Windows.)
|
121
|
+
|
122
|
+
[mach-o]: https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/MachOTopics/1-Articles/executing_files.html
|
123
|
+
[brew]: http://brew.sh/
|