python psycopg2 postgresql: getting "permission denied for relation settings" - python

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...

Related

cx_Oracle giving ORA-01031 Insufficient privileges Logging in as SYSDBA

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/

How to add SUPER priviledge to MySQL in pythonanywhere?

I am using PythonAnywhere to host my web application for testing purpose. My frontend and python script is working fine. Now I want to connect it to MySQL database. I have uploaded my .sql file to the mysite folder and trying to restore it using this syntax:
mysql -u username -h username.mysql.pythonanywhere-services.com 'username$scm' < ab.sql
as told in Backing up (and restoring) MySQL databases (where username=created username) but it's throwing this error:
ERROR 1419 (HY000) at line 88: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_
trust_function_creators variable)
I've tried to fix this error by following this How to grant super privilege to the user? but still it's throwing error:
ERROR 1044 (42000): Access denied for user 'username'#'%' to database 'username$scm'
Please help me out.
Take a look at the answer on PythonAnywhere forums:
You would not be able to get super privileges on MySQL (only
postgres). Could you disable binary logging before doing the restore?
You could either try to edit the ab.sql file to take out that line, or
turn it off from wherever you were creating the sqldump originally,
and doing the sqldump again.

MySQL connection error message after deployment in Pythonanywhere

I deployed my python program in pythonanywhere. This program should be connected to MySQL. I set up the database and I configured my database setting in the config.ini file as below:
[mysql]
host =psedemo.mysql.pythonanywhere-services.com
database =psedemo$psedemo_test
user =psedemo
password =QAZwsx123
When I am running the program from the shell, I am getting the following error in database connection:
"Exception - 1142 (42000): SELECT command denied to user 'psedemo'#'10.0.0.207' for table 'pseapp_osd_products'".
Any idea what is the issue? (I am sure that databases/table are created and my setting also is right)
I am changing my answer as I reviewed Pythonanywhere just now. It looks like you have created a python app there and you are using the MySQL db from them. Your password for Pythonanywhere is different from the MySQL password. When you first generate the database, they ask you to create a password for it and mention that it is different from your Pythonanywhere password. You can create a new password in the database page in case you forgot the password.
Click on your database name in their UI to launch the mysql console. Check the following command.
SHOW GRANTS;
It will most probably show that your user has all the GRANTS.
Now, use the connection details on the page, and the password you created, and try to connect again.
You can also check their help page to connect to MySQL https://help.pythonanywhere.com/pages/UsingMySQL/
try using user = "root" for your user
Another source of this error could be a typo in a join. See some of the discussion here and check that the query you're running is correct.

How to import data via MySQL Workbench with SSH?

I'm trying to upload data to my MySQL database on the PythonAnywhere server hosting via SSH (I have a paid account). I have three databases (alter$default, alter$ip_data and alter$visitor_data) from within the PythonAnywhere interface.
Using the online instructions (here) I can successfully connect to the server via SSH using MySQL Workbench, and see the three databases in the schemas window (Click here to view image of schemas list).
I can successfully add tables to the database of my choice, but when I try to add data I get Error Code: 1045. Access denied for user 'alter'#'%' (using password: YES).
I have tried troubleshooting:
For SELECT user(); it returns alter#10.0.0.89
For SELECT current_user(); it returns alter#%
For SHOW GRANTS; it returns:
GRANT USAGE ON *.* TO 'alter'#'%' IDENTIFIED BY PASSWORD <secret> WITH MAX_USER_CONNECTIONS 6
GRANT ALL PRIVILEGES ON 'alter$default' .* TO 'alter'#'%'
GRANT ALL PRIVILEGES ON 'alter$visitor_data' .* TO 'alter'#'%'
GRANT ALL PRIVILEGES ON 'alter$ip_data' .* TO 'alter'#'%'
It appears that I have the necessary privileges granted and am correctly connected to the MySQL server - so why will it not let me write to the database? Is the .csv file in the wrong place? I can't use the 'root' user as that is surely the PythonAnywhere administrator account?
Extra details:
The SQL query for writing to the database - that returns "access denied" - is:
LOAD DATA INFILE 'VALUES.CSV'
INTO TABLE ip_data_table
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 0 LINES;
It's the infile that is causing the permission denied. You need to start the mysql client with the --local-infile=1 flag.

Using PyMySQL, I can't connect to RDS

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\'#\'%\''

Categories

Resources