I'm trying to connect to an Oracle 19 database using unixODBC 2.3.7.
I'm using the Oracle Developer Days VirtualBox VM.
When trying to troubleshoot via isql I always get this error:
# isql -v -3 oracledsn
[HY000][unixODBC][Oracle][ODBC][Ora]ORA-12545: Connect failed because target host or object does not exist
[ISQL]ERROR: Could not SQLConnect
Sadly I can't reproduce it now, but when last trying it I always had
[IM004][unixODBC][Driver Manager]Driver's SQLAllocHandle on SQL_HANDLE_HENV failed
[ISQL]ERROR: Could not SQLConnect
This is the same error message I get from my (proprietary) C++ code, so I'm pretty sure the problem is just the connection settings.
I have checked https://www.connectionstrings.com/oracle/ but none of the combinations work.
Here are all my config settings:
# odbcinst -j -130-
unixODBC 2.3.7
DRIVERS............: /usr/local/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources
USER DATA SOURCES..: /home/florian/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
# cat /usr/local/etc/odbcinst.ini
[oraclex]
Description = Oracle ODBC driver for Oracle 19
Driver = /mnt/libsqora.so.19.1
Setup =
FileUsage =
CPTimeout =
CPReuse =
Driver Logging = 7
[ODBC]
Trace = Yes
TraceFile = /tmp/odbc.log
ForceTrace = Yes
Pooling = No
DEBUG = 1
# cat ~/.odbc.ini
[oracledsn]
Driver = oraclex
Server = 10.1.6.19
Port = 1521
Uid = system
Pwd = oracle
Database = orclcdb/orcl/"<empty>"
ORA-12545: Connect failed because target host or object does not exist
I also tried ServerName
ServerName = //10.1.6.19/orclcdb or //10.1.6.19/orcl
[28000][unixODBC][Oracle][ODBC][Ora]ORA-01017: invalid username/password; logon denied
Here's the /tmp/odbc.log:
[ODBC][18832][1564563250.044774][__handles.c][460]
Exit:[SQL_SUCCESS]
Environment = 0x1fd7780
[ODBC][18832][1564563250.044854][SQLSetEnvAttr.c][189]
Entry:
Environment = 0x1fd7780
Attribute = SQL_ATTR_ODBC_VERSION
Value = 0x3
StrLen = 0
[ODBC][18832][1564563250.044886][SQLSetEnvAttr.c][381]
Exit:[SQL_SUCCESS]
[ODBC][18832][1564563250.044914][SQLAllocHandle.c][377]
Entry:
Handle Type = 2
Input Handle = 0x1fd7780
[ODBC][18832][1564563250.044944][SQLAllocHandle.c][493]
Exit:[SQL_SUCCESS]
Output Handle = 0x1fd8090
[ODBC][18832][1564563250.044983][SQLConnect.c][3721]
Entry:
Connection = 0x1fd8090
Server Name = [oracledsn][length = 9 (SQL_NTS)]
User Name = [NULL]
Authentication = [NULL]
UNICODE Using encoding ASCII 'ANSI_X3.4-1968' and UNICODE 'UCS-2LE'
DIAG [HY000] [Oracle][ODBC][Ora]ORA-12545: Connect failed because target host or object does not exist
[ODBC][18832][1564563250.082037][SQLConnect.c][4244]
Exit:[SQL_ERROR]
[ODBC][18832][1564563250.082070][SQLGetDiagRec.c][677]
Entry:
Connection = 0x1fd8090
Rec Number = 1
SQLState = 0x7fffeabcac60
Native = 0x7fffeabcac5c
Message Text = 0x7fffeabcac70
Buffer Length = 500
Text Len Ptr = 0x7fffeabcac5a
[ODBC][18832][1564563250.082092][SQLGetDiagRec.c][726]
Exit:[SQL_SUCCESS]
SQLState = HY000
Native = 0x7fffeabcac5c -> 12545
Message Text = [[unixODBC][Oracle][ODBC][Ora]ORA-12545: Connect failed because target host or object does not exist
I've also been trying out this C code from https://www.easysoft.com/developer/languages/c/odbc_tutorial.html#connect_full - basically the same result.
# cat test2.c
# compile with gcc -I ../include test2.c -o test2 -lodbc
#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
/*
* see Retrieving ODBC Diagnostics
* for a definition of extract_error().
*/
static void extract_error(
char *fn,
SQLHANDLE handle,
SQLSMALLINT type);
main() {
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
SQLRETURN ret; /* ODBC API return status */
SQLCHAR outstr[1024];
SQLSMALLINT outstrlen;
/* Allocate an environment handle */
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
/* We want ODBC 3 support */
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);
/* Allocate a connection handle */
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
/* Connect to the DSN mydsn */
ret = SQLDriverConnect(dbc, NULL, "DSN=oracledsn;", SQL_NTS,
outstr, sizeof(outstr), &outstrlen,
SQL_DRIVER_COMPLETE);
if (SQL_SUCCEEDED(ret)) {
printf("Connected\n");
printf("Returned connection string was:\n\t%s\n", outstr);
if (ret == SQL_SUCCESS_WITH_INFO) {
printf("Driver reported the following diagnostics\n");
//extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
}
SQLDisconnect(dbc); /* disconnect from driver */
} else {
fprintf(stderr, "Failed to connect\n");
//extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
}
/* free up allocated handles */
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
}
As another point reference I can connect to said Oracle Dev VM with sqlplus from another machine like this:
./sqlplus sys/oracle#10.1.6.19/orclcdb as sysdba
SQL>
./sqlplus system/oracle#10.1.6.19/orclcdb
SQL>
On the VM I have a file /u01/app/oracle/product/version/db_1/network/admin/tnsnames.ora but I am not completely sure if I also need one on the client?
ORCLCDB=localhost:1521/orclcdb
ORCL=
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)
I finally found the solution, although this is for 12.2.0.1 and not 19
# cat .odbc.ini
[oracledsn]
Driver=oracle
UID=system
PWD=oracle
DBQ=192.168.178.32:1521/ORCLCDB
ServerName=//192.168.178.32:1521/ORCLCDB
cat /usr/local/etc/odbcinst.ini
[oracle]
Description = foo
Driver = /mnt/libsqora.so.19.1
Driver Logging = 7
UsageCount=1
FileUsage=1
[ODBC]
Trace = Yes
TraceFile = /tmp/odbc.log
ForceTrace = Yes
Pooling = No
# LD_LIBRARY_PATH=. isql -v oracledsn system oracle
+---------------------------------------+
| Connected! |
I have no Oracle-specific environment variables set, but if it works if I take the value of ServerName verbatim for TWO_TASK.
I had success with oracle 19c, with one minor change here - remove the "//" from ServerName i.e.
ServerName=192.168.178.32:1521/ORCLCDB
Related
I am trying to send a UDP packet from Omnett ++ TSN Device to a standard Host through a TSN switch that is connected to a Router.
However, I get the following check_and_cast error:-
check_and_cast(): Cannot cast(inet::physicallayer::signal*)app[0]-0 to type 'inet::physicallayer::EthernetSignalBase *' in module (inet::EthernetMac) of router.eth[0].mac
My omnetpp.ini udp app setup is as follows.
extends = omnetpptsnnetworksample
#Source application
*.tsnDevice1.numApps = 1
*.tsnDevice1.app[0].typename = "UdpSourceApp"
*.tsnDevice1.app[0].source.packetLength = 10B
*.tsnDevice1.app[0].source.productionInterval = 1ms
*.tsnDevice1.app[0].io.destAddress = "ue[0]"
*.tsnDevice1.app[0].io.destPort = 1000
*.tsnDevice1.app[0].source.clockModule = "^.^.clock"
#Sink application
*.standardHost[*].numApps = 1
*.standardHost[*].app[*].typename = "UdpSinkApp"
*.standardHost[*].app[*].io.localPort = 1000
Where did I go wrong?
TsnDevice and TsnSwitch have LayeredEthernetInterface by default, but StandardHost has EthernetInterface. The two interfaces are not compatible (not sure if they should be or not). So by setting standardHost's ethernet interface type to LayeredEthernetInterface, it should work:
*.standardHost[*].eth[*].typename = "LayeredEthernetInterface"
Implemented WinAppDriver
Trying to start Windows Application Driver C#
var p = new Process();
p.StartInfo.FileName = #"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe";
p.Start();
Error:
Address 'http://127.0.0.1:4723/' is already in use
Failed to initialize: 0x80004005
Error running it Windows Application Driver c# code:
The HTTP request to the remote WebDriver server for URL http://localhost:4723/session timed out after 60 seconds.
C# Code:
var appPath = #"ApplicationPath";
var windowsApplicationDriverUrl = "http://localhost:4723";
var appiumOptions = new AppiumOptions();
appiumOptions.AddAdditionalCapability("app", appPath);
session = new WindowsDriver<WindowsElement>(new Uri(windowsApplicationDriverUrl), appiumOptions);
Run
netstat -a -n -o | find "4723"
I find the PID is for
TCP 0.0.0.0:4723 0.0.0.0:0 LISTENING 4
The System runs the PID
tasklist
Image Name PID Session Name Session# Mem Usage
========================= ======== ================ =========== ============
System Idle Process 0 Services 0 8 K
System 4 Services 0 1,440 K
Windows Application driver doesn't run because something is already hogging the port.
Is this anti-virus? How do you fix?
Ultimately decided to just run the application on another port.
ProcessStartInfo startInfo = new ProcessStartInfo(#"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe");
startInfo.Arguments = "28399";
var p = Process.Start(startInfo);
Console.WriteLine("start");
var appPath = #"ApplicationPath";
var windowsApplicationDriverUrl = "http://localhost:28399";
var appiumOptions = new AppiumOptions();
appiumOptions.AddAdditionalCapability("app", appPath);
session = new WindowsDriver<WindowsElement>(new Uri(windowsApplicationDriverUrl), appiumOptions);
I use a vb application that connect to an Oracle service by an Oracle client 10g:
Protected cnS3 As OracleConnection
cnS3 = New OracleConnection(String.Format("Data Source={0};user id={1}; password={2}; ", _
"myDataSource10", "dbUser", "dbUserPassword"))
But the db provider has dismissed the Oracle user and has provided me a proxy user. It told me to connect with the proxy user and Oracle client 11.2.0.4.
So I've installed the Oracle client 11g and created a new ODBC DSN "myDataSource11" with Oracle 11g version (tested and worked in the ODBC Data Sources Interface).
But when replace the code as follows:
Protected cnS3 As OracleConnection
cnS3 = New OracleConnection(String.Format("Data Source={0};user id={1}; password={2}; ", _
"myDataSource11", "dbProxyUser[dbUser]", "dbProxyUserPassword"))
I have the error: [OracleException (0x80131938): ORA-12154: TNS:could not resolve the connect identifier specified
I have also tried with this code:
oradb = "Data Source=(DESCRIPTION = (ADDRESS_LIST = (LOAD_BALANCE = ON) (FAILOVER = ON)" _
+ "(ADDRESS=(PROTOCOL=tcp)(HOST=myhostname)(PORT=5555))" _
+ "(ADDRESS=(PROTOCOL=tcp)(HOST=myhostname2)(PORT=5555)))(CONNECT_DATA" _
+ "= (SERVICE_NAME = myServiceName )));" _
+ "User Id=dbProxyUser[dbUser];Password=dbProxyUserPassword;"
cnS3 = New OracleConnection(oradb)
And in this case the error is [ArgumentException: Lunghezza dell'opzione di connessione "user id" non valida. La lunghezza massima รจ 30.]
I've resolved replacing the OracleConnection with OdbcConnection.
The proxy user has been added also in the web.config and the password of the proxy user has been added in the odbc, as explained at https://community.oracle.com/tech/developers/discussion/2209660/ora-01005-null-password-given-error-on-windows-7
I have been trying to configure the "External Procedures" Feature for my Oracle Database 18c on Windows 10.
The documentation claims, to set up this feature, it is basically just necessary to set the environment values in extrproc.ora - which in my case is just one line of: SET EXTPROC_DLLS=ANY (for testing purposes).
I have created a DLL to test my configuration by using Delphi with the following code:
library testdll;
function Sum(x, y: Integer): Integer; stdcall;
begin
Result := x + y;
end;
function Subtract(x, y: Integer): Integer; stdcall;
begin
Result := x - y;
end;
procedure TEST; stdcall;
begin
end;
exports
TEST,
Sum,
Subtract;
begin
end.
So my first question would be: Do I need to compile the DLLs as x64 or as x86? Also, is the calling convention stdcall compatible with Oracle 18c?
Furthermore I have created a Library Alias in my database using:
CREATE OR REPLACE LIBRARY MySchema.TESTDLL AS 'C:\testdll.dll'
The external procedure has been published by
create or replace PROCEDURE TESTPROCEDURE
AS LANGUAGE C
NAME "TEST"
LIBRARY TESTDLL;
Now that I have everything setup on the database, I tried calling the procedure:
begin
TESTPROCEDURE();
end;
But when I tried calling it, I get the following Error:
ORA-06520: PL/SQL: Fehler beim Laden der externen Library
ORA-06522: Unable to load DLL
ORA-06512: in "MySchema.TESTPROCEDURE", Zeile 1
ORA-06512: in Zeile 2
06520. 00000 - "PL/SQL: Error loading external library"
*Cause: An error was detected by PL/SQL trying to load the external
library dynamically.
*Action: Check the stacked error (if any) for more details.
Info:
The database spawns the extproc.exe properly, after I call the procedure
How do I get this work properly and are Delphi DLLs even compatible?
This is my listener.ora file:
# listener.ora Network Configuration File: C:\app\oracle\product\18.0.0\dbhomeXE\NETWORK\ADMIN\listener.ora
# Generated by Oracle configuration tools.
DEFAULT_SERVICE_LISTENER = XE
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = C:\app\oracle\product\18.0.0\dbhomeXE)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:C:\app\oracle\product\18.0.0\dbhomeXE\bin\oraclr18.dll")
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
And this is my tnsnames.ora file:
# tnsnames.ora Network Configuration File: C:\app\oracle\product\18.0.0\dbhomeXE\NETWORK\ADMIN\tnsnames.ora
# Generated by Oracle configuration tools.
XE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)
LISTENER_XE =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
)
)
Any ideas what could be wrong with my configuration?
Edit:
This is the .c dll example code from the database:
/*
** Copyright (c) 1997 by Oracle Corporation
**
** NAME
** EXTERN.C
**
** DESCRIPTION
** Sample Windows NT External Procedure: find_max
**
*/
#include <windows.h>
#define NullValue -1
/*
This function simply returns the returns the larger of x and y.
*/
long __declspec(dllexport) find_max(long x,
short x_indicator,
long y,
short y_indicator,
short *ret_indicator)
{
/* It can be tricky to debug DLL's that are being called by a process
that is spawned only when needed, as in this case.
Therefore try using the DebugBreak(); command.
This will start your debugger. Uncomment the following line and
you can step right into your code.
*/
/* DebugBreak(); */
/* first check to see if you have any nulls */
/* Just return a null if either x or y is null */
if ( x_indicator==NullValue || y_indicator==NullValue) {
*ret_indicator = NullValue;
return(0);
} else {
*ret_indicator = 0; /* Signify that return value is not null */
if (x >= y) return x;
else return y;
}
}
And this is the make.bat file:
REM USAGE: just type MAKE
if (%PROCESSOR_ARCHITECTURE%)==(IA64) goto win64_ia64
if (%PROCESSOR_ARCHITECTURE%)==(AMD64) goto win64_amd64
cl -I. /LD -Zi extern.c /link msvcrt.lib /nod:libcmt /DLL
goto fi
:win64_ia64
cl /DWIN64 /D_WIN64 /DSS_64BIT_SERVER /D_IA64_=1 -I. /LD -Zi extern.c /link msvcrt.lib /nod:libcmt /DLL
goto fi
:win64_amd64
cl /GS- /DWIN64 /D_WIN64 /DSS_64BIT_SERVER /D_AMD64_=1 -I. /LD -Zi extern.c /link msvcrt.lib /MACHINE:AMD64 /nod:libcmt /DLL
goto fi
:fi
Based on the information provided, I can see the following:
The C example is compiled as a 64 bit DLL.
The C example does not specify a calling convention and so uses the default which is cdecl.
The example C functions accept 5 arguments, but your functions accept only 2.
I am trying to run a very simple python script from Oracle. Oracle is on the same linux box as the script. It opens a file and creates a checksum. It is triggered by a 'recon' user within oracle.
Running the script from within Oracle works fine as long as the file owner is 'oracle', or the group is 'oinstall' (oracle's default group), or the public is set to rx, the script works.
The problem is that we must use a different user:group, and we cannot use public permissions. We added the oracle user to the file's group.
uid=54321(oracle) gid=54321(oinstall) groups=54321(oinstall),202175(efs_data)
When running from within Oracle as we did before, it now fails, however, when sudo'ing into the oracle user and running the script directly, it works so we know the linux permissions are ok.
What could cause this? I guess Oracle is doing some other sort of access check overlaying the linux permissions, and this ignores the secondary groups and looks at gid only.
as 'recon' schema:
set serveroutput on size unlimited
declare
x number;
begin
x := run_cmd('/home/oracle/bin_dir/pytest.py');
dbms_output.put_line('return:' || x);
end;
run_cmd:
create or replace function RUN_CMD( p_cmd in varchar2) return number as
language java
name 'Util.RunThis(java.lang.String) return integer';
Util.RunThis:
import java.io.*;
import java.lang.*;
public class Util extends Object
{
public static int RunThis(java.lang.String args)
{
Runtime rt = Runtime.getRuntime();
int rc = -1;
try
{
Process p = rt.exec(args);
int bufSize = 4096;
BufferedInputStream bis =
new BufferedInputStream(p.getInputStream(), bufSize);
int len;
byte buffer[] = new byte[bufSize];
// Echo back what the program spit out
while ((len = bis.read(buffer, 0, bufSize)) != -1)
System.out.write(buffer, 0, len);
rc = p.waitFor();
}
catch (Exception e)
{
e.printStackTrace();
rc = -1;
}
finally
{
return rc;
}
}
}
/home/oracle/bin_dir/pytest.py:
#! /usr/bin/python -W ignore::DeprecationWarning
import paramiko
import logging
import datetime
import pwd
import md5
import os
def test_file_open(local_file):
print 'Trying to open: '+ local_file
logging.info('Trying to open: ' + local_file)
local_file_data = open(local_file, "rb").read()
checksum = md5.new(local_file_data).hexdigest()
return checksum
def main():
logging.basicConfig(filename='/mounts/users/dmz/pytest.log', level=logging.INFO)
logging.info('==========================================')
logging.info('START: ' + str(datetime.datetime.now()))
logging.info('getuid: ' + pwd.getpwuid( os.getuid() ).pw_name)
logging.info('geteuid: ' + pwd.getpwuid( os.geteuid() ).pw_name)
checksum = test_file_open('/test.txt')
print 'Success!, checksum: ' + checksum
logging.info('Success! checksum: ' + checksum)
logging.info('END: ' + str(datetime.datetime.now()))
if __name__ == '__main__':
main()
Output (with oracle as file owner):
-rwxrwx---. 1 oracle efs_data 0 Jun 7 19:56 /test.txt
INFO:root:==========================================
INFO:root:START: 2018-06-07 19:45:32.005429
INFO:root:getuid: oracle
INFO:root:geteuid: oracle
INFO:root:Trying to open: /test.txt
INFO:root:Success! checksum: 9f1e1404fd72b59121d45a8beb4dab5d
INFO:root:END: 2018-06-07 19:45:32.007078
Output (with permissions only via group association):
-rwxrwx---. 1 root efs_data 0 Jun 7 19:57 /test.txt
INFO:root:==========================================
INFO:root:START: 2018-06-07 19:44:15.748559
INFO:root:getuid: oracle
INFO:root:geteuid: oracle
INFO:root:Trying to open: /test.txt
I have a similar problem with DIRECTORY and external tables where linux group access is seemingly ignored. I was able to solve by using an acl and letting the oracle user have the rights it needs while letting the ownership of the file stay will another user.
ll test.txt
-rwx------. 1 lunc users 940 Jun 13 09:34 test.txt
setfacl -m u:oracle:rwx test.txt
getfacl test.txt
# file: test.txt
# owner: lunc
# group: users
user::rwx
user:oracle:rwx
group::---
mask::rwx
other::---
ll test.txt
-rwxrwx---+ 1 lunc users 940 Jun 13 09:34 test.txt
Oracle accepts this (at least for external tables) and is able to access the file.