I am trying to connect Oracle remote database server using Python cx_Oracle. In sqlplus I do use "sqlplus / as sysdba" for connecting server using putty Console and i am to login successfully. Can you please help me on this why it was throwing this error.
import cx_Oracle
tns= cx_Oracle.makedsn('ip', port, SERVICE NAME = 'SID')
db = cx_Oracle.connect('SYS', 'password', tns, mode=cx_Oracle.SYSDBA)
It was throwing Error :
cx_Oracle Database Error ORA-01031: insufficient privileges
I already made one normal DB user and tried connecting with and it was Successful.
db = cx_Oracle.connect('USERNAME', 'password', tns)
You should be able to do most (all?) of the kind of things you mentioned with the normal "DBA" role. SYSDBA is often only necessary when doing things that require restart of the database, software and patch installation, or with backup/recovery scenarios, and is insanely overpowered for day-to-day uses. Depending on your version of Oracle, it is capable of bypassing many security features entirely, and is generally not safe to use within most scripts and applications for that reason. Use should be limited to things that only SYSDBA can do.
Additionally, the SYS user may not be allowed to connect over the network (you're using a TNS connection), as it is authenticated by the server operating system which implies local login only. That's why "sqlplus / as sysdba" works when you're logged in to the database server.
Consider the following:
If you must have actual SYSDBA privileges and nothing else will do, grant the SYSDBA role to another user and use that instead. As #Littlefoot suggested, never use the SYS or SYSTEM accounts for day-to-day administrative work, either on the server or remotely.
Never embed username and password in your scripts or application code, especially for an account that powerful. Use an Oracle Wallet to hold encrypted user credentials instead, or better yet prompt the user to enter them at runtime. Putting credentials like that directly in a script is a sure way to fail a security audit.
Follow the principle of least privilege and don't use a SYSDBA or DBA-role enabled account for anything else other than what you need those specific privileges to do (adding files, etc.). Use lesser accounts where possible.
When using privileged accounts like those with DBA or SYSDBA privileges over the network, you should encrypt all communications.
See these links for details:
https://pmdba.wordpress.com/2020/01/13/how-to-hide-oracle-passwords-in-a-script/
https://pmdba.wordpress.com/2014/10/16/database-account-password-storage/
Related
I would like to have some help with the parameters passed under the connection string through a .py file trying connection to my Oracle Apex workspace database:
connection = cx_Oracle.connect("user", "password", "dbhost.example.com/dbinstance", encoding="UTF-8")
On the login page at "apex.oracle.com", we have to pass the following information:
Can I assume that the "user" parameter is equal to the USERNAME info, the "password" parameter is equal to the PASSWORD info and the "dbinstance" parameter is equal to the WORKSPACE info?
And what about the hostname? What is it expected as parameter? How do I find it?
Thank you very much for any support.
Those parameters are not equivalent. An APEX workspace is a logical construct that exists only within APEX; it does not correspond to a physical database instance. Username and password do not necessarily correspond to database users, as APEX is capable of multiple methods of authentication.
APEX itself runs entirely within a single physical database. An APEX instance supports multiple logical workspaces, each of which may have its own independent APEX user accounts that often (usually) do not correspond to database users at all. APEX-based apps may have entirely separate authentication methods of their own, too, and generally do not use the same users defined for the APEX workspaces.
When an APEX application does connect to a database to run, it connects as a proxy user using an otherwise unprivileged database account like APEX_PUBLIC_USER.
If you want to connect Python to APEX, you would have to connect like you would any other web app: through the URL using whatever credentials are appropriate to the user interface and then parsing the HTML output, or through an APEX/ORDS REST API (that you would have to first build and deploy).
If you want to connect to the database behind APEX, then you would need an appropriately provisioned database (not APEX) account, credentials and connectivity information provided by the database administrator.
I have been through numerous other posts (to name only a few) but still stuck. The configuration is simple enough that I'll detail everything, though I think only a few of the following are relevant:
Running psql as user postgres on Ubuntu 16.04, I've created database qedadmin with 3 tables: networks, devices, and settings; there's also a sequence relation networks_networkid_seq owned by networks.networkId.
I am writing a python script to run on the same server using psycopg2 which needs to execute a SELECT on the settings table. Many examples show scripts connecting as user 'postgres', and indeed this works perfectly for me. However, I suppose it's better to use a less-privileged user for this sort of thing, so I created a user qedserver with a password.
Using this new user and password and localhost in the psycopg2 connection string, I can successfully get a connection and a cursor (and if I use incorrect user or password values, the connection fails, so I know the defined user and password and the authentication from python are all working). However, all of my attempts to execute a SELECT statement on table settings are returning code 42501: permission denied for relation settings.
I initially granted user qedserver only SELECT privileges, and only on table settings:
GRANT SELECT ON settings TO qedserver;
Since that did not work, I've gradually escalated privileges to the point that now user qedserver has ALL PRIVILEGES on all 3 tables, on the sequence relation, and on the database:
GRANT ALL PRIVILEGES ON settings TO qedserver;
GRANT ALL PRIVILEGES ON devices TO qedserver;
GRANT ALL PRIVILEGES ON networks TO qedserver;
GRANT ALL PRIVILEGES ON networks_networkid_seq TO qedserver;
GRANT ALL PRIVILEGES ON DATABASE qedadmin TO qedserver;
but I am still getting "permission denied for relation settings".
To be clear, changing just the connection string in my python script from one for user postgres to one for user qedserver makes the difference between success and failure, so I am not providing python code because I think it's irrelevant (but I can do so if you think it would help).
What am I missing?
Edited to add: there is no linux user named qedserver; I don't think there needs to be but perhaps I'm wrong about that? (further edit: I just did this experiment and it made no difference.)
Updates: Per #klin's comment and link, I can see that all of the privileges have been successfully granted: qedserver has privileges arwdDxt on the networks, devices, and settings tables, and rwU privileges on the networks_networkid_seq sequence relation; and \l reports Access Privileges on the qedadmin database of =Tc/postgres + postgres=CTc/postgres + qedserver=CTc/postgres.
I have also edited the config file (/etc/postgresql/10/main/postgresql.conf on my system) to set log_error_verbosity=VERBOSE and sent a SIGHUP to the postgresql process to re-read the config file. This added another line to the error log (/var/log/postgresql/postgresql-10-main.log on my system) for each failed attempt; now the log shows (the new line is the middle one):
qedserver#qedadmin ERROR: 42501: permission denied for relation settings
qedserver#qedadmin LOCATION: aclcheck_error, aclchk.c:3410
qedserver#qedadmin STATEMENT: SELECT * FROM settings WHERE deviceId = 10020;
What else can I look at or try to make headway?
Editing 4 months later to add: this was all for a new project for which I thought it would be advantageous to use postgresql for a few reasons; hitting this problem so early in development and being unable to resolve it over several days, I gave up and went with mysql instead. Not exactly a "solution" to the OP so I'm not adding it as an answer...
I'm getting the following error when trying to obtain GSSAPI credentials on my machine:
server_creds = gssapi.Credentials(usage='init', name=server_name)
GSSError: Major (851968): Unspecified GSS failure. Minor code may provide more information, Minor (2): Key table file '/etc/krb5.keytab' not found
Here is what I have already found in Kerberos keytab introduction:
A keytab is a file containing pairs of Kerberos principals and encrypted keys (these are derived from the Kerberos password). You can use this file to log into Kerberos without being prompted for a password. The most common personal use of keytab files is to allow scripts to authenticate to Kerberos without human interaction, or store a password in a plaintext file.
Well, it's completely acceptable for me even if my program will actually require human interaction in order to authenticate. Is there any way to use Kerberos client on end-user system without /etc/krb5.keytab file, even if it means asking password on each authentication?
It makes no sense to "even if it means asking password on each authentication". This defeats the purpose of Kerberos.
You can do the following:
Your user does "kinit" in the shell or similar via a login manager
You have a binding for gss_acquire_cred_with_password() for Python
Evaluate both
Using PyMySQL, I get pymysql.err.OperationalError: (1045, u"Access denied for user 'my_user'#'<MY_IP_ADDRESS>' (using password: YES)"), however, I can login from the command line or MySQL Workbench using the same credentials on this machine. And, I can connect to localhost using PyMySQL. Here's my sample test code:
import pymysql
prod_conn = pymysql.connect(
host='correct-host-name.us-west-2.rds.amazonaws.com',
user='my_user',
password='correct_password',
port=3306,
database='my_db')
However, using mysql -hcorrect-host-name.us-west-2.rds.amazonaws.com -umy_user -pcorrect_password -P3306 -Dmy_db from the command line on the same machine, I get in just fine.
After Googling, I tried checking the grants for the user and I believe that the user is setup correctly. SHOW GRANTS FOR CURRENT_USER() returns
Grants for my_user#%
'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER ON *.* TO \'my_user\'#\'%\' WITH GRANT OPTION'
I tried checking SELECT USER(), CURRENT_USER(); and get back
USER() CURRENT_USER()
'my_user#<MY_IP_ADDRESS>' 'my_user#%'
So, it seems that the user is setup properly, which I suspected since I can connect through other options. I also tried both suggestions from https://forums.aws.amazon.com/thread.jspa?messageID=707103 (specifically, using a different parameter group with log_bin_trust_function_creators == 1 and using a password without punctuation) to no avail.
I want to use this in a lambda function, so I really want to use PyMySQL to keep this a python only solution rather than trying MySQLDB or another library.
I don't think there are any anonymous users after reviewing SELECT user,host FROM mysql.user;
user host
'my_user' '%'
'mysql.sys' 'localhost'
'rdsadmin' 'localhost'
Appreciate any other thoughts this community might have on how to proceed...
I solved this by creating a new user. I only needed read privileges for this user, so it's a better approach than using the default user with such high permissions. I'm still not sure why the original one didn't work, but here's what ended up working:
# Grants for my_new_user#%
'GRANT SELECT ON *.* TO \'my_new_user\'#\'%\''
I am using Pycharm and try to link to a mssql server. When I link to a server that requires SQL authentication, the connect is created successfully. However, when I try to link to a server that requires my Windows Authentication, even though I use my username or password of windows log in, I cannot connect successfully. May I know what should be a proper way to setup if it is windows authentication.
I am using the below code:
import pymssql
conn=pymssql.connect(host="10.xx.xx.xx",user="CORPORATE/mywindowsloginname",password="mypassword",database="BIC_reference")
cur=conn.cursor()y
cur.execute('SELECT top 10 * FROM dbo.hi_invoiceline')
print (cur.fetchall())
in order to use Windows Authentication you have to add the property trusted_connection='yes' to your connection string. In this case you can omit user and password:
conn=pymssql.connect(host="10.xx.xx.xx",database="BIC_reference",trusted_connection='yes')
When using Windows Authentication, you should not specify any user credentials. The following should work assuming your Windows account has the relevant permissions:
conn=pymssql.connect(host="10.xx.xx.xx",database="BIC_reference")
I have tested this using pymssql-2.1.3. Using this version there was no need to specify trusted_connection='yes' (see apomene's answer), however, you may want to try that as well in case the above snippet doesn't work.