Pergunta

I'm wondering if anyone has any success in writing a C/C++ application that uses the Oracle OCI API and authenticates using an Oracle wallet.

I have successfully created the wallet using mkstore and have stored the credentials in it. My tnsnames.ora and sqlnames.ora files have the correct contents, and my ORACLE_HOME and ORACLE_SID environment variables are set correctly as I can use sqlplus /@XE to authenticate a sqlplus session successfully using it.

Within the same terminal I have created a simple C program that allocates the OCIEnv, OCIServer, OCIError and OCIsvcCtx handles and calls OCIEnvCreate(). That all works fine.

I then try calling any one of the "connect" functions, such as OCILogon (also tried OCILogon2 and OCISessionPoolCreate as well), and I always get "invalid username/password". I am trying to call it as I see it defined for my invocation of sqlplus i.e null username and password with 0 length, and dbname of "XE" with appropriate length. (I've also tried dbnames of "@XE" and "/@XE" for completeness)

I see there is a security API for opening wallets and interrogating their contents, but I assumed this was application that want to interact directly with the contents of the wallet (i.e add/remove credentials etc). Maybe this is an incorrect assumption on my part...

There is precious little info out there as to how to do this programatically, so if anyone has any pointers, or a small working example that can simply connect to the database in this way I would be very grateful.

Many thanks

Ben

Foi útil?

Solução

That's what I found also, there is precious little info out there on how to do this programatically. I finally figured it out by experiementing. It seems you have your sqlnet.ora and tnsnames.ora files set up correctly, so all you need to do is modify your code for attaching to the server and starting the session.

When attaching to the server, your dblink text string should be your connect string in tnsnames.ora for your oracle wallet entry. In your case "XE".

OCIServerAttach (OCIServer *srvhp, OCIError *errhp, CONST text *dblink, sb4 dblink_len, ub4 mode )

When beginning your session, credt should be set to OCI_CRED_EXT. This validates the credentials externally and since SQLNET.WALLET_OVERRIDE = TRUE is in sqlnet.ora, It uses oracle wallet to validate the connect string. Also, having credt set to OCI_CRED_EXT ignores the username and password session attributes.

OCISessionBegin (OCISvcCtx *svchp, OCIError *errhp, OCISession *usrhp, ub4 credt, ub4 mode );

That's it. I didn't use OCILogin or OCISessionPoolCreate in my code.

Good luck, David M.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top