Re: dynamic lib ignored even after "found" in "install_driver(Oracle) failed: Can't load..." cgi problem



okay, here is my final comment for those interested in a solution to this problem. the (slight, imo) drawback to my solution is that it is a bit of a hack in terms of where an administrator might want to choose to install libraries (or perhaps it's because i am not a good administrator that i want to place them in places other than where they "should" be placed :} )

the solution i found is this: i moved the directory containing libclntsh.so (and associated others) under /usr/lib, which is a location that apache seems to trust, as opposed to where i had originally placed this directory. to be precise, when i installed the directory instantclient_10_2 at

/usr/local/instantclient_10_2/

apache refused to load /usr/local/instantclient_10_2/libclntsh.so.10.1 or any of the libraries located there. but when i moved this directory and its contents to

/usr/lib/instantclient_10_2/

then i could get apache to load /usr/lib/instantclient_10_2/libclntsh.so.10.1 and all the other instantclient libraries therein. (if anyone knows why apache seems averse to these libraries existing somewhere other than "trusted" locations like /lib and /usr/lib, please comment. and is this configurable? i saw nothing in httpd.conf that looked like any such configuration to me.)

it took some fiddling with ldconfig to update the system's search path to find them, but afterwards, it was not a problem (this issue might be addressed via LD_LIBRARY_PATH as well, but i'll leave that as an exercise for someone else... :)

so, if i knew then what i know now, here are the steps _I_ would use were i to install the oracle instantclient such that the DBD::Oracle module would work when used in an apache 2.0 CGI:

as me:

download instantclient-basic-linux32-10.2.0.3-20061115.zip, instantclient-sdk-linux32-10.2.0.3-20061115.zip, and instantclient-sqlplus-linux32-10.2.0.3-20061115.zip into my home directory.

as root:

% unsetenv ORACLE_HOME # just to show it is not needed
% unsetenv LD_LIBRARY_PATH # same

% cd /usr/local/src
% mv ~me/instantclient-*.zip .
% unzip instantclient-basic-linux32-10.2.0.3-20061115.zip
% unzip instantclient-sdk-linux32-10.2.0.3-20061115.zip
% unzip instantclient-sqlplus-linux32-10.2.0.3-20061115.zip


there is now a directory here named instantclient_10_2, which has all the goodies i need in it.

% mv -i instantclient_10_2 /usr/lib/
% cd /etc/
% echo "/usr/lib/instantclient_10_2" >> ld.so.conf
% /sbin/ldconfig
% /sbin/ldconfig -p | grep instantclient # check for /usr/lib/instantclient libs in the cache

if you will be using a tnsnames.ora file that the web server needs to be able to find, you need to add it here:

% cd /usr/lib/instantclient_10_2/
% mkdir network network/admin # if they don't already exist
% cp -i /your/copy/of/tnsnames.ora /usr/lib/instantclient_10_2/network/admin/


this should be all that is needed, but here are some additional notes for the testing of the instantclient software, connecting to an oracle database, and what my test perl script looks like and the details showing it successfully connecting itself, both from the command line and via apache CGI:

as me again:

% unsetenv ORACLE_HOME # for starts
% unsetenv ORACLE_SID #
% unsetenv TWO_TASK #
% unsetenv LD_LIBRARY_PATH #
% cat cgi-bin/test2.pl

#!/usr/bin/perl -w

use Carp;
use diagnostics;
use DBI;

# standard html header for browsers to grok
print "Content-type: text/html\n\n";

# print environment
foreach my $key (keys(%ENV)) {
if ($key =~ /^(LD|ORACLE)/) {
print "$key = $ENV{$key}<BR>\n";
}
}

print "<BR><BR>\n";

my $dbh = DBI->connect("DBI:Oracle:$ENV{'ORACLE_SID'}",
'scott','tiger',
{ RaiseError => 1,
PrintError => 0,
AutoCommit => 0, } ) || print "connection failed\n" ;

print "dbh = $dbh\n\n"; # show that we got a valid database handle
$dbh->disconnect; # clean up


to run this from the command line, i need:

% setenv ORACLE_SID xyz # this needs to correspond to an entry in tnsnames.ora
% perl test2.pl
Content-type: text/html

ORACLE_SID = xyz<BR>
<BR><BR>
dbh = DBI::db=HASH(0x991d0c0)

% unsetenv ORACLE_HOME
% perl test2.pl
Content-type: text/html

ORACLE_SID = xyz<BR>
<BR><BR>
dbh = DBI::db=HASH(0x92f60c0)

%

note that i DID NOT need to set ORACLE_HOME. on the other hand, for this to work, i did need a valid tnsnames.ora file located at network/admin/tnsnames.ora relative to the location of the instantclient libraries (/usr/lib/instantclient_10_2/network/admin/tnsnames.ora to be exact here.) i also could run it this way by placing tnsnames.ora in my home directory as .tnsnames.ora, but this location will do me no good when i want apache to run the script as a cgi. i believe that ORACLE_HOME need only be set for direct use of the sqlplus client. for a perl script using DBD::Oracle, this linking has already been configured in (it appears.)


[the rest of this has to do with getting my web server to work correctly with an ORACLE_SID environment variable i need passed into my CGI. if you hard code this string in your CGI, you should be ready to go now. i've just included this for my own notes and for anyone who might be interested...]

okay, now i will try to run the script as an apache cgi script. here is the resulting error (because i still need to do a little bit of configuring of the web server so that it sees the ORACLE_SID environment variable the script needs):

[Tue Sep 04 09:12:59 2007] [error] [client 127.0.0.1] Uncaught exception from user code:
[Tue Sep 04 09:12:59 2007] [error] [client 127.0.0.1] \tDBI connect('','scott',...) failed: ORA-12162: TNS:net service name is incorrectly specified (DBD ERROR: OCIServerAttach) at /var/www/cgi-bin/test2.pl line 19
[Tue Sep 04 09:12:59 2007] [error] [client 127.0.0.1] at /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi/DBI.pm line 598
[Tue Sep 04 09:12:59 2007] [error] [client 127.0.0.1] \tDBI::__ANON__('undef', 'undef') called at /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi/DBI.pm line 648
[Tue Sep 04 09:12:59 2007] [error] [client 127.0.0.1] \tDBI::connect('DBI', 'DBI:Oracle:', 'scott', 'tiger', 'HASH(0x9fecd40)') called at /var/www/cgi-bin/test2.pl line 19

the problem here is that the second argument of the connect call is incomplete because $ENV{'ORACLE_SID'} in my script is not set. in order to set this as an environment variable in the shell apache is started in, i add the line

export ORACLE_SID=${ORACLE_SID:-xyz}

in the /etc/sysconfig/httpd file. [granted, setting such a "global" environment variable for apache is a bit heavy-handed; we probably want a control more local to the specific cgi running, but this is how i set it up initially, so i'll figure out a nicer way later...]

if i run the script now, there's still a problem because apache does not pass its environment into particular CGIs unless you tell it to do so in the httpd.conf file. so after adding this line to my httpd.conf file:

PassEnv ORACLE_SID

finally, my script should work. here is the result of calling the test2.pl cgi now:

ORACLE_SID = xyz

dbh = DBI::db=HASH(0x9f23ec4)

so we are finally getting a valid handle to our remote oracle database in the CGI. yay!

hope this helps some people.

cheers,

bruce

Bruce Sears wrote:
ahhh... we are getting closer (?)

after running

strace -fFo trace_file /usr/sbin/httpd -X

it looks like it is some sort of permissions problem after all (?)

.
.
.
6177 open("/usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi/auto/DBD/Oracle/Oracle.so", O_RDONLY) = 3
6177 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\360@\0"..., 512) = 512
6177 fstat64(3, {st_mode=S_IFREG|0555, st_size=386943, ...}) = 0
6177 old_mmap(NULL, 194448, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x111000
6177 old_mmap(0x140000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2e000) = 0x140000
6177 close(3) = 0
6177 open("/usr/lib/perl5/5.8.5/i386-linux-thread-multi/CORE/libclntsh.so.10.1", O_RDONLY) = -1 ENOENT (No such file or directory)
6177 open("/etc/ld.so.cache", O_RDONLY) = 3
6177 fstat64(3, {st_mode=S_IFREG|0644, st_size=82246, ...}) = 0
6177 old_mmap(NULL, 82246, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7ecf000
6177 close(3) = 0
6177 open("/usr/local/instantclient_10_2/libclntsh.so.10.1", O_RDONLY) = -1 EACCES (Permission denied)
6177 open("/lib/tls/i686/sse2/libclntsh.so.10.1", O_RDONLY) = -1 ENOENT (No such file or directory)
.
.
.

weird. it looks to me like apache SHOULD have read access to this file, but it doesn't. am i missing some sort of configuration detail regarding apache and permissions granted a cgi? i thought once the server started a cgi, it basically had the run of the place (as much access to the system as the apache user itself...)

okay, different tack. i edited the /etc/passwd file to set a login shell for apache so i could su apache. i did this, and i am able to read libclntsh.so.10.1 (i ran 'od libclntsh.so.10.1', and was not denied permission. got lots of digits <8 :)

so, at least as a logged in user, apache does have read access to this library. so why the "Permission denied" when trying to open it for my test cgi?

big clue finally... i found that if i copied libclntsh.so.10.1 into a "trusted" library location (/lib in this case, it does load. (and just making a link to the library in /usr/local/instantclient_10_2/ does not work, not surprisingly.)) now the failure is at the loading of another lib in /usr/local/instantclient_10_2/. i'm guessing this must be part of the apache configuration, so i'll look more carefully in the apache conf file now...

okay, i found nothing obvious there. but somewhere, something is configuring these permissions restrictions into the httpd executables. any ideas anyone? do i really have to move all my libraries into /lib (or /usr/lib probably works, too... ??)


thanks again for the help,

bruce



Bruce Sears wrote:
thanks for the input tim (and charles),

i have checked all the permissions, and these should be fine for access by the apache user. and when i ran as myself (not root), the command line execution did fine, too.

-rwxrwxr-x 1 root root 18825267 Nov 15 2006 /usr/local/instantclient_10_2/libclntsh.so.10.1
drwxr-xr-x 4 root root 4096 Aug 30 16:56 /usr/local/instantclient_10_2/
drwxr-xr-x 20 root root 4096 Aug 30 17:26 /usr/local
drwxr-xr-x 15 root root 4096 Jun 14 18:03 /usr
drwxr-xr-x 23 root root 4096 Aug 27 14:38 /

i will try the strace and see what i can see...

thanks again,

bruce


Tim Kirby wrote:
On 8/30/07 4:51 PM, "Bruce Sears" <bsears@xxxxxxxxxxxxxxxxx> wrote:

thanks for bearing with this. it's too much detail, but perhaps not
enough (sigh).

Just glancing at this before retiring for the night; someone else will
probably give you a real answer, but two things come to mind/might be
worth looking at/whatever...

(1) have you verified permissions for the library in question for whatever
user the CGI is running as? I know the error didn't say permission
denied, but you never know...

(2) I would feel inclined to run the web server under strace, feeding the
output to a file somewhere (make sure you're following children) and
run your test case. There you will see the actual system calls that
are being invoked and you should see a 'stat' and a real errno as to
why it didn't open the library when it should have done. The trouble
with debug aids of the kind you're using is it really depends on the
people who wrote the debug code to have done the right thing everywhere.

Color me cynical.

So, there's my $0.02 FWIW. I may be in lala land, but that's what I would
be looking at assuming I didn't misread what you posted.

Good luck

Tim





Relevant Pages

  • Re: Rivet and snit....
    ... You will need to set up Apache to make sure your directories are ready ... to execute CGI (if you plan to say turn your welcome page into a CGI ... script to generate the page). ... indicate it's intent - then process it as a form submission script. ...
    (comp.lang.tcl)
  • Re: PHP and MySQL passwords
    ... I'll assume your on a linux system with apache as your webserver. ... If it is shared is PHP running as a module or cgi? ... If you code the user/pass in a file anyone with an account on the ... file either by reading it directly or by writing a script to read it. ...
    (alt.php)
  • Cant setup mod_perl and DBD::Sybase
    ... I've been using DBD::Sybase with CGI scripts. ... I thought that perhaps I needed to set up $SYBASE from Apache, ... The fact is that if I call the perl script from a shell script and then ... Director de Sistemas de Información ...
    (perl.dbi.users)
  • Re: Help getting Perl/CGI running on OS X localhost with apache
    ... >>shtml = SSI, not CGI ... you can call a script using SSI directives. ... http://localhost/ your document root is /users/peter/Sites. ... Normally Apache set up questions should be asked in an Apache related ...
    (comp.lang.perl.misc)
  • PHP, shared server, permissions, etc.
    ... I'm trying to configure my personal server (an old PowerMac G4 Server ... Like, if Apache runs as nobody/nobody, and someone has a PHP script ... If everyone's in the same group, one user's script can access/modify ... Permissions and ownership -- All users and Apache in a 'www' group? ...
    (comp.infosystems.www.servers.unix)