Hiding plain text password with sqlplus command line - oracle

I wish to use a sqlplus command with password hidden from view such that it doesn't show up on ps -ef command.
I know there are a lot of solutions provided all over internet blogs but most of them seem to require admin privileges and I have restricted access on this server. And rest of them just don't seem to work me.
The command that I am currently using is as below:
sqlplus -s SOME_USERNAME/SOME_PASSWORD#somedns.intra.com:1500/SOMESID #some.sql
Legend:
SOME_USERNAME: schema/user
SOME_PASSWORD: password
SOMESID: SID for this DB.
#some.sql: An sql file containing insert statements.
Any pointers are much appreciated.
Update: Forgot to mention that this sqlplus command will be used inside a shell script.

How do I input the password from within a shell script in this case?
You can use a heredoc:
sqlplus -s /nolog <<!EOF
connect SOME_USERNAME/SOME_PASSWORD#somedns.intra.com:1500/SOMESID
#some.sql
!EOF
The connect and #some.sql are treated as an input stream to SQL*Plus, as if you'd typed them in an interactive session, and are not part of the initial call to the executable - so the connection details don't appear in ps output.
You can also use variables if you want to, incidentally, as the variable expansion happens in the shell before it passes the stream to the executable - so even though SQL*Plus wouldn't understand say $PASSWD, referring to that in the heredoc works and the actual variable value is passed.

Use sqlplus -s SOME_USERNAME#\"somedns.intra.com:1500/SOMESID\" #some.sql and enter your password on the command line.
Or use external authentication and don't use a password at all
Finally, SOMESID is not a SID, it's a Service Name. The Easy Connect syntax you use only works with service names. SIDs are very very old-school.

Related

sqlplus does not execute the query if it is called by a ssh external connection

I have a script lying into a Unix server which looks like this:
mainScript.sh
#some stuff here
emailScript.sh $PARAM_1 $PARAM_2
#some other stuff here
As you can see, mainScript.sh is calling another script called emailScript.sh.
The emailScript.sh is supposed to perform a query via sqlplus, then parse the results and return them via email if any.
The interesting part of the code in emailScript.sh is this:
DB_SERVER=$1
USERNAME=$2
PASSWORD=$3
EVENT_DATE=$4
LIST_AUTHORIZED_USERS=$5
ENVID=$6
INTERESTED_PARTY=$7
RAW_LIST=$(echo "select distinct M_OS_USER from MX_USER_CONNECTION_DBF where M_EVENT_DATE >= to_date('$EVENT_DATE','DD-MM-YYYY') and M_OS_USER is not null and M_OS_USER not in $LIST_AUTHORIZED_USERS;" | sqlplus -s $USERNAME/$PASSWORD#$DB_SERVER)
As you can see, all I do is just creating the variable RAW_LIST executing a query with sqlplus.
The problem is the following:
If I call the script mainScript.sh via command line (PuTTy / KiTTy), the sqlplus command works fine and returns something.
If I call the script mainScript.sh via an external job (a ssh connection opened on the server via a Jenkins job), the sqlplus returns nothing and takes 0 seconds, meaning it doesn't even try to execute itself.
In order to debug, I've printed all the variables, the query itself in order to check if something wasn't properly set: everything is correctly set.
It really seems that the command sqlplus is not recognized, or something like this.
Would you please have any idea on how I can debug this? Where should I look the issue?
You need to consider few things here. While you are running the script, from which directory location you are executing the script? And while you are executing the script from your external application from which directory location it is executing the script. Better use full path to the script like /path/to/the/script/script.sh or use cd /path/to/the/script/ command to go to the script directory first and execute the script. Also check execute permission for your application. You as an user might have permission to execute the script or sql command but your application does not have that permission. Check the user id for your application and add that into the proper group.

sqlplus command not found zabbix

I'm working and discovering the world of Zabbix. In particular I am trying to monitor an Oracle database with the Zabbix server through an external script. Given that other external scripts work, however, I created one with sqlplus, but on Zabbix I get "command not found". Can you tell me why?
The code is:
check.pl
#!/usr/bin/perl
use strict;
use warnings;
my $out=`echo "select * from v$version;" | sqlplus user/password#ip_database:port`;
print $out;
The code is very simple.
I created an item as always, passed as type "external check" and a key I entered my script. Can anyone solve my problem? Also if I was not clear, just ask for more information rather than "insult" on the forum: Thanks to everyone in advance
I RESOLVED IT WITH:
echo "/usr/lib/oracle/11.2/client64/lib" > /etc/ld.so.conf.d/oracle.conf
echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/oracle/11.2/client64/lib" >> /etc/profile
THANKS TO ALL!!!!
Apparently, your zabbix server does not have the necessary environment to find sqlplus. You could simply use the full path to sqlplus in your script (but that alone might not be enough) or create a wrapper script that sets all the necessary environment variables for your script.
From TFM:
The command will be executed as the user Zabbix server runs as, so any
access permissions or environment variables should be handled in a
wrapper script, if necessary, and permissions on the command should
allow that user to execute it.
You also have to configure the sqlplus libraries required to run sqlplus. The script which you use to start the zabbix server you can configure below oracle things in the startup script so that zabbix can find all necessary libraries to run.
export ORACLE_HOME={path to Oracle Client}
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${ORACLE_HOME}/lib
If still there are issues related to .so files then there must be some issues in your SQL client installation.

Login to Informix as a different user using dbaccess

I'm trying to write a shell script that when called, uses the dbaccess command line tool to pull data from a table.
echo "unload to data.csv delimiter '|' select * from tbl_extract;" | time dbaccess $database_name;
Now when I run this, it runs with my own account. Dbaccess seems to use the logged in Unix account to login to the database. But I want this to run under a different account. How do I get dbaccess to accept a username and password to use a different account?
As #Johnathan Leffler correctly pointed out, if you use the CONNECT clause in the SQL, you cannot avoid being prompted for the password. What you need to do is ensure that the dbaccess process itself runs as a different user.
You can either use sudo, e.g.:
echo "unload to data.csv delimiter '|' select * from tbl_extract;" |\
sudo -u __run_as_user__ time dbaccess $database_name;
NB You may need to configure the sudoers file to permit execution and not prompt for password.
The better alternative would be to set setuid on the script, so that the whole script runs as __run_as_user__. This has the added bonus of ensuring any files (such as data.csv) are also owned by that user, and you don't run into permissions problems.
You will need to use the explicit CONNECT statement, and will need to provide the password:
{
echo "CONNECT TO $database USER 'whoever';"
echo "UNLOAD TO 'data.csv' DELIMITER '|' SELECT * FROM tbl_extract;"
} |
time dbaccess - -
Note the delicate balancing of quotes; the user name must be in a string, and you want to specify the database via a variable, so the string as a whole must be in double quotes and it is simpler to use single quotes around the name than backslash double quote \" twice (which would also work, even if the user name is in a variable).
This will prompt you for the user's password.
Alternatives include using sudo or su to change identity to the user.
My SQLCMD program (unrelated to Microsoft's johnny-come-lately program of the same name) has a variety of ways of connecting to a database with a user name and scripting the password so that there is no interaction needed, ranging from the wholly insecure (command line argument; string in script) to the relatively secure (string in a file that can only be read by the user). It can be used instead of DB-Access — I use it instead of DB-Access, but then I wrote it (mainly because I wasn't happy with the interface provided by DB-Access or its predecessor command).

using grep in a script which prompt user for input

I have written one shell script which ask for some username and password from standart input.
Once username and password is typed there is a output depending upon the parameters passed in the script.
Say my script name is XYZ.ksh.
Now my problem is that users of these script want to use want to use this script in conjugation with other shell commands like grep, less, more, wc etc.
Normally yes they can use
XYZ.ksh | grep abc
But in my case since XYZ is prompting for username and password we are not able to use "|" in front of that. It blocks forever.
I just wanted to know how can I implement the functinality.
What I tried
I tried taking input of "more commands " from user where user types things like "| grep abc"
but when i used this input in my script it did not work.
Use <<< like this:
XYZ.ksh <<< "your inputs" | grep abc
In your script you can test to see if stdout is connected to a terminal with:
if [[ -t 1 ]]
That way you can supress the prompt if the output is not going to the console.
Alternatively, with your "more commands" solution, run the command connected to a named pipe.
There are multiple solutions commonly used for this kind of problem but none of them is perfect :
Read password from standard input. It makes it really hard to use the script in pipes. This method is used by commands that deal with changing passwords : passwd, smbpasswd
Provide username and password in the command line parameters. This solution is good for using the script in pipes, but command line can be viewed by anyone, using ps -ef for exemple. This is used by mysql, htpasswd, sqlplus, ...
Store username and password unencrypted in a file in user's home directory. This solution is good for using the script in pipes, but the script must check if the file is visible or modifiable by other users. This is used by mysql
Store private key in local file and public key in distant file, as used by SSH. You must have a good encryption knowledge to do this correctly (or rely on SSH), but it's excellent for use in pipes, even creating pipes accross different machines !
Don't deal with passwords, and assume that if a user is logged in in the system, he has the right to run the program. You may give execute privilege only to one group to filter who can use the program. This is used by sqlplus from Oracle, VirtualBox, games on some Linux distributions, ...
My preferred solution would be the last, as the system is certainly better than any program I could write with regard to security.
If the password is used to login to some other service, then I would probably go for the private file containing the password.
One less-than-optimal possibility is to display the prompt to stderr instead of stdout.
echo -n "Username:" >/dev/stderr
A better solution would be to check stdin of the shell. If it's a terminal, then open it for writing and redirect to that file. Unfortunately, I'm not sure how to do that in bash or ksh; perhaps something like
echo -n "Username:" >/dev/tty
You can use (I assume you are reading username and password in your script with read)
(
read -p "user:" USER
read -p "pass:" PASS
) < /dev/tty > /dev/tty
and you'll be able to run
$ cmd | XYZ.ksh
However, I agree with other answers: just don't ask for user and password and give the correct permissions to the script to allow access.

How "sqlplus /" works

I was wondering how sqlplus takes the username and password in connect statement "sqlplus /".
How can I change the configuration if i want to connect with "sqlplus /" with different user. It Might seems awkward but in my script "sqlplus /" is harcoded and we cannot change this. Just I want to connect with different user using same command.
From the Oracle documentation:
/
Represents a default logon using operating system authentication. In a default logon, SQL*Plus typically attempts to log you in using the username OPS$name, where name is your operating system username. Note that the prefix "OPS$" can be set to any other string of text.
For example, you may wish to change the settings in your INIT.ORA parameters file to LOGONname or USERIDname. See the Oracle9i Database Administrator's Guide for information about operating system authentication.
So it uses your operating system details to construct your Oracle user name, meaning that you probably can't set an arbitrary name.
The Oracle initialisation parameter for specifying the prefix is OS_AUTHENT_PREFIX and its default value id OPS$.
One thing you could do, if you cannot change the script which calls sqlplus, is to insert your own sqlplus script in the path before the Oracle one, along the lines of (not thoroughly tested):
#!/bin/bash
if [[ "$1" != "/" ]] ; then
$ORACLE_HOME/bin/sqlplus "$#"
exit
fi
shift
$ORACLE_HOME/bin/sqlplus $MY_ORA_USER/$MY_ORA_PWD "$#"
This would then be the one called by your script and it would check the first parameter to see if it was the simple /. If not, it would call the real sqlplus with the same parameters.
Otherwise, it would replace the / with a user/password formed from the MY_ORA_* environment variables.

Resources