Reputation: 59
I have unixODBC set up correctly on my CentOS7 server to work with my Transoft ODBC driver, and I can successfully connect and query the databases I am trying to hit using it in root with the command:
isql -v 'DSN' 'user' 'pwd'
I took the next step and created a PHP script to run a query.
$connect = odbc_connect("integra.udd","user","pwd");
$query = "SELECT Company1,Product,Vendor,Description1 FROM ICMAST WHERE Company1=1 LIMIT 5";
$result = odbc_exec($connect, $query);
while(odbc_fetch_row($result)){
$product = odbc_result($result, 2);
$desc = odbc_result($result, 4);
print "\n$product $desc<br />";
}
If I execute this in root using PHP odbctest.php
, it works and I get the results I should. Furthermore, I can drop to the apache user with su -s /bin/bash apache
and run it, and it works. (I verified that the Apache server uses apache
as the user by running the command echo exec ('whoami');
in a PHP script)
However, if I go to a browser and run it, I get the following error:
Warning: odbc_connect(): SQL error: [unixODBC][Driver Manager]Can't open lib '/usr/usql/sqlaccess/libtsodbc.so' : file not found, SQL state 01000 in SQLConnect in /var/www/html/2m/odbctest.php on line 10
The shared object file is not found when running with Apache, but when running from any user, it is.
First, I assumed a permissions issue, so I changed ownership of the libtsodbc.so
file to apache:apache
. No change.
Then I checked permissions on the file, it's set to 555
, so should be executable by users.
I then tried a PHP script run in a browser that checks if the file exists in that path. Here is the script I ran:
<?php
$filename = '/usr/usql/sqlaccess/libtsodbc.so';
if (file_exists($filename)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
?>
It returned that the file exists, so PHP can see it even when Apache is executing the script.
I discarded the idea that it is a SELinux or Firewalled thing as it doesn't even get to the point where it is trying to connect, it fails when it tries to find the shared object library file. So the issue has to be internal on the server.
Finally, I thought maybe this had to do with the shared library path, even though it is looking at the actual path to the file in the error and not finding it. So I tried adding the following line to my PHP script to set the LD_LIBRARY_PATH
:
putenv("LD_LIBRARY_PATH=/usr/usql/sqlaccess/");
No change, still gives the file not found error.
I'm sure it is something simple as I am a total Linux beginner, but I am at a loss as to what to try next. Any ideas? What else is different between a user running a PHP script and Apache running a PHP script?
Edit to add
libtsodbc.so
, php
, and httpd
file command output:
[root@intranetserver /]# file /usr/usql/sqlaccess/libtsodbc.so
/usr/usql/sqlaccess/libtsodbc.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped
[root@intranetserver /]# file /usr/bin/php
/usr/bin/php: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=70ddc88b357d818240da4d4b3db50790c7913822, stripped
[root@intranetserver /]# file /usr/sbin/httpd
/usr/sbin/httpd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0890c878aa1d1a620d5c65d25a13d11cc2fdf96a, stripped
Upvotes: 2
Views: 978
Reputation: 9444
Looks likely to a bitness mismatch to me.
Check output of these commands. They should all match --
file /usr/usql/sqlaccess/libtsodbc.so
file `which php` # the runtime PHP
file `which httpd` # the typical name of the apache executable
find / -name mod_php -exec file {} \;
# mod_php is the PHP module for Apache
# if you know where mod_php is on your box, you can just do
# file /path/to/mod_php
Upvotes: 2